diff --git a/google/cloud/firestore_admin_v1/gapic_metadata.json b/google/cloud/firestore_admin_v1/gapic_metadata.json index fa9d675d8..73f37c418 100644 --- a/google/cloud/firestore_admin_v1/gapic_metadata.json +++ b/google/cloud/firestore_admin_v1/gapic_metadata.json @@ -10,6 +10,11 @@ "grpc": { "libraryClient": "FirestoreAdminClient", "rpcs": { + "CreateBackupSchedule": { + "methods": [ + "create_backup_schedule" + ] + }, "CreateDatabase": { "methods": [ "create_database" @@ -20,6 +25,16 @@ "create_index" ] }, + "DeleteBackup": { + "methods": [ + "delete_backup" + ] + }, + "DeleteBackupSchedule": { + "methods": [ + "delete_backup_schedule" + ] + }, "DeleteDatabase": { "methods": [ "delete_database" @@ -35,6 +50,16 @@ "export_documents" ] }, + "GetBackup": { + "methods": [ + "get_backup" + ] + }, + "GetBackupSchedule": { + "methods": [ + "get_backup_schedule" + ] + }, "GetDatabase": { "methods": [ "get_database" @@ -55,6 +80,16 @@ "import_documents" ] }, + "ListBackupSchedules": { + "methods": [ + "list_backup_schedules" + ] + }, + "ListBackups": { + "methods": [ + "list_backups" + ] + }, "ListDatabases": { "methods": [ "list_databases" @@ -70,6 +105,16 @@ "list_indexes" ] }, + "RestoreDatabase": { + "methods": [ + "restore_database" + ] + }, + "UpdateBackupSchedule": { + "methods": [ + "update_backup_schedule" + ] + }, "UpdateDatabase": { "methods": [ "update_database" @@ -85,6 +130,11 @@ "grpc-async": { "libraryClient": "FirestoreAdminAsyncClient", "rpcs": { + "CreateBackupSchedule": { + "methods": [ + "create_backup_schedule" + ] + }, "CreateDatabase": { "methods": [ "create_database" @@ -95,6 +145,16 @@ "create_index" ] }, + "DeleteBackup": { + "methods": [ + "delete_backup" + ] + }, + "DeleteBackupSchedule": { + "methods": [ + "delete_backup_schedule" + ] + }, "DeleteDatabase": { "methods": [ "delete_database" @@ -110,6 +170,16 @@ "export_documents" ] }, + "GetBackup": { + "methods": [ + "get_backup" + ] + }, + "GetBackupSchedule": { + "methods": [ + "get_backup_schedule" + ] + }, "GetDatabase": { "methods": [ "get_database" @@ -130,6 +200,16 @@ "import_documents" ] }, + "ListBackupSchedules": { + "methods": [ + "list_backup_schedules" + ] + }, + "ListBackups": { + "methods": [ + "list_backups" + ] + }, "ListDatabases": { "methods": [ "list_databases" @@ -145,6 +225,16 @@ "list_indexes" ] }, + "RestoreDatabase": { + "methods": [ + "restore_database" + ] + }, + "UpdateBackupSchedule": { + "methods": [ + "update_backup_schedule" + ] + }, "UpdateDatabase": { "methods": [ "update_database" @@ -160,6 +250,11 @@ "rest": { "libraryClient": "FirestoreAdminClient", "rpcs": { + "CreateBackupSchedule": { + "methods": [ + "create_backup_schedule" + ] + }, "CreateDatabase": { "methods": [ "create_database" @@ -170,6 +265,16 @@ "create_index" ] }, + "DeleteBackup": { + "methods": [ + "delete_backup" + ] + }, + "DeleteBackupSchedule": { + "methods": [ + "delete_backup_schedule" + ] + }, "DeleteDatabase": { "methods": [ "delete_database" @@ -185,6 +290,16 @@ "export_documents" ] }, + "GetBackup": { + "methods": [ + "get_backup" + ] + }, + "GetBackupSchedule": { + "methods": [ + "get_backup_schedule" + ] + }, "GetDatabase": { "methods": [ "get_database" @@ -205,6 +320,16 @@ "import_documents" ] }, + "ListBackupSchedules": { + "methods": [ + "list_backup_schedules" + ] + }, + "ListBackups": { + "methods": [ + "list_backups" + ] + }, "ListDatabases": { "methods": [ "list_databases" @@ -220,6 +345,16 @@ "list_indexes" ] }, + "RestoreDatabase": { + "methods": [ + "restore_database" + ] + }, + "UpdateBackupSchedule": { + "methods": [ + "update_backup_schedule" + ] + }, "UpdateDatabase": { "methods": [ "update_database" diff --git a/google/cloud/firestore_admin_v1/services/firestore_admin/async_client.py b/google/cloud/firestore_admin_v1/services/firestore_admin/async_client.py index 51b09cc19..00f6084ad 100644 --- a/google/cloud/firestore_admin_v1/services/firestore_admin/async_client.py +++ b/google/cloud/firestore_admin_v1/services/firestore_admin/async_client.py @@ -45,6 +45,7 @@ from google.api_core import operation as gac_operation # type: ignore from google.api_core import operation_async # type: ignore from google.cloud.firestore_admin_v1.services.firestore_admin import pagers +from google.cloud.firestore_admin_v1.types import backup from google.cloud.firestore_admin_v1.types import database from google.cloud.firestore_admin_v1.types import database as gfa_database from google.cloud.firestore_admin_v1.types import field @@ -53,6 +54,7 @@ from google.cloud.firestore_admin_v1.types import index from google.cloud.firestore_admin_v1.types import index as gfa_index from google.cloud.firestore_admin_v1.types import operation as gfa_operation +from google.cloud.firestore_admin_v1.types import schedule from google.cloud.location import locations_pb2 # type: ignore from google.longrunning import operations_pb2 # type: ignore from google.protobuf import duration_pb2 # type: ignore @@ -107,6 +109,12 @@ class FirestoreAdminAsyncClient: _DEFAULT_ENDPOINT_TEMPLATE = FirestoreAdminClient._DEFAULT_ENDPOINT_TEMPLATE _DEFAULT_UNIVERSE = FirestoreAdminClient._DEFAULT_UNIVERSE + backup_path = staticmethod(FirestoreAdminClient.backup_path) + parse_backup_path = staticmethod(FirestoreAdminClient.parse_backup_path) + backup_schedule_path = staticmethod(FirestoreAdminClient.backup_schedule_path) + parse_backup_schedule_path = staticmethod( + FirestoreAdminClient.parse_backup_schedule_path + ) collection_group_path = staticmethod(FirestoreAdminClient.collection_group_path) parse_collection_group_path = staticmethod( FirestoreAdminClient.parse_collection_group_path @@ -117,6 +125,8 @@ class FirestoreAdminAsyncClient: parse_field_path = staticmethod(FirestoreAdminClient.parse_field_path) index_path = staticmethod(FirestoreAdminClient.index_path) parse_index_path = staticmethod(FirestoreAdminClient.parse_index_path) + location_path = staticmethod(FirestoreAdminClient.location_path) + parse_location_path = staticmethod(FirestoreAdminClient.parse_location_path) common_billing_account_path = staticmethod( FirestoreAdminClient.common_billing_account_path ) @@ -2053,6 +2063,1000 @@ async def sample_delete_database(): # Done; return the response. return response + async def get_backup( + self, + request: Optional[Union[firestore_admin.GetBackupRequest, dict]] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> backup.Backup: + r"""Gets information about a backup. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import firestore_admin_v1 + + async def sample_get_backup(): + # Create a client + client = firestore_admin_v1.FirestoreAdminAsyncClient() + + # Initialize request argument(s) + request = firestore_admin_v1.GetBackupRequest( + name="name_value", + ) + + # Make the request + response = await client.get_backup(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.firestore_admin_v1.types.GetBackupRequest, dict]]): + The request object. The request for + [FirestoreAdmin.GetBackup][google.firestore.admin.v1.FirestoreAdmin.GetBackup]. + name (:class:`str`): + Required. Name of the backup to fetch. + + Format is + ``projects/{project}/locations/{location}/backups/{backup}``. + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.firestore_admin_v1.types.Backup: + A Backup of a Cloud Firestore + Database. + The backup contains all documents and + index configurations for the given + database at a specific point in time. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = firestore_admin.GetBackupRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.get_backup, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def list_backups( + self, + request: Optional[Union[firestore_admin.ListBackupsRequest, dict]] = None, + *, + parent: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> firestore_admin.ListBackupsResponse: + r"""Lists all the backups. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import firestore_admin_v1 + + async def sample_list_backups(): + # Create a client + client = firestore_admin_v1.FirestoreAdminAsyncClient() + + # Initialize request argument(s) + request = firestore_admin_v1.ListBackupsRequest( + parent="parent_value", + ) + + # Make the request + response = await client.list_backups(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.firestore_admin_v1.types.ListBackupsRequest, dict]]): + The request object. The request for + [FirestoreAdmin.ListBackups][google.firestore.admin.v1.FirestoreAdmin.ListBackups]. + parent (:class:`str`): + Required. The location to list backups from. + + Format is ``projects/{project}/locations/{location}``. + Use ``{location} = '-'`` to list backups from all + locations for the given project. This allows listing + backups from a single location or from all locations. + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.firestore_admin_v1.types.ListBackupsResponse: + The response for + [FirestoreAdmin.ListBackups][google.firestore.admin.v1.FirestoreAdmin.ListBackups]. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = firestore_admin.ListBackupsRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.list_backups, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def delete_backup( + self, + request: Optional[Union[firestore_admin.DeleteBackupRequest, dict]] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> None: + r"""Deletes a backup. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import firestore_admin_v1 + + async def sample_delete_backup(): + # Create a client + client = firestore_admin_v1.FirestoreAdminAsyncClient() + + # Initialize request argument(s) + request = firestore_admin_v1.DeleteBackupRequest( + name="name_value", + ) + + # Make the request + await client.delete_backup(request=request) + + Args: + request (Optional[Union[google.cloud.firestore_admin_v1.types.DeleteBackupRequest, dict]]): + The request object. The request for + [FirestoreAdmin.DeleteBackup][google.firestore.admin.v1.FirestoreAdmin.DeleteBackup]. + name (:class:`str`): + Required. Name of the backup to delete. + + format is + ``projects/{project}/locations/{location}/backups/{backup}``. + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = firestore_admin.DeleteBackupRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.delete_backup, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + async def restore_database( + self, + request: Optional[Union[firestore_admin.RestoreDatabaseRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation_async.AsyncOperation: + r"""Creates a new database by restoring from an existing backup. + + The new database must be in the same cloud region or + multi-region location as the existing backup. This behaves + similar to + [FirestoreAdmin.CreateDatabase][google.firestore.admin.v1.CreateDatabase] + except instead of creating a new empty database, a new database + is created with the database type, index configuration, and + documents from an existing backup. + + The [long-running operation][google.longrunning.Operation] can + be used to track the progress of the restore, with the + Operation's [metadata][google.longrunning.Operation.metadata] + field type being the + [RestoreDatabaseMetadata][google.firestore.admin.v1.RestoreDatabaseMetadata]. + The [response][google.longrunning.Operation.response] type is + the [Database][google.firestore.admin.v1.Database] if the + restore was successful. The new database is not readable or + writeable until the LRO has completed. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import firestore_admin_v1 + + async def sample_restore_database(): + # Create a client + client = firestore_admin_v1.FirestoreAdminAsyncClient() + + # Initialize request argument(s) + request = firestore_admin_v1.RestoreDatabaseRequest( + parent="parent_value", + database_id="database_id_value", + backup="backup_value", + ) + + # Make the request + operation = client.restore_database(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.firestore_admin_v1.types.RestoreDatabaseRequest, dict]]): + The request object. The request message for + [FirestoreAdmin.RestoreDatabase][google.firestore.admin.v1.RestoreDatabase]. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.api_core.operation_async.AsyncOperation: + An object representing a long-running operation. + + The result type for the operation will be + :class:`google.cloud.firestore_admin_v1.types.Database` + A Cloud Firestore Database. + + """ + # Create or coerce a protobuf request object. + request = firestore_admin.RestoreDatabaseRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.restore_database, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Wrap the response in an operation future. + response = operation_async.from_gapic( + response, + self._client._transport.operations_client, + database.Database, + metadata_type=gfa_operation.RestoreDatabaseMetadata, + ) + + # Done; return the response. + return response + + async def create_backup_schedule( + self, + request: Optional[ + Union[firestore_admin.CreateBackupScheduleRequest, dict] + ] = None, + *, + parent: Optional[str] = None, + backup_schedule: Optional[schedule.BackupSchedule] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> schedule.BackupSchedule: + r"""Creates a backup schedule on a database. + At most two backup schedules can be configured on a + database, one daily backup schedule with retention up to + 7 days and one weekly backup schedule with retention up + to 14 weeks. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import firestore_admin_v1 + + async def sample_create_backup_schedule(): + # Create a client + client = firestore_admin_v1.FirestoreAdminAsyncClient() + + # Initialize request argument(s) + request = firestore_admin_v1.CreateBackupScheduleRequest( + parent="parent_value", + ) + + # Make the request + response = await client.create_backup_schedule(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.firestore_admin_v1.types.CreateBackupScheduleRequest, dict]]): + The request object. The request for + [FirestoreAdmin.CreateBackupSchedule][google.firestore.admin.v1.FirestoreAdmin.CreateBackupSchedule]. + parent (:class:`str`): + Required. The parent database. + + Format ``projects/{project}/databases/{database}`` + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + backup_schedule (:class:`google.cloud.firestore_admin_v1.types.BackupSchedule`): + Required. The backup schedule to + create. + + This corresponds to the ``backup_schedule`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.firestore_admin_v1.types.BackupSchedule: + A backup schedule for a Cloud + Firestore Database. + This resource is owned by the database + it is backing up, and is deleted along + with the database. The actual backups + are not though. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent, backup_schedule]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = firestore_admin.CreateBackupScheduleRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if backup_schedule is not None: + request.backup_schedule = backup_schedule + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.create_backup_schedule, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def get_backup_schedule( + self, + request: Optional[Union[firestore_admin.GetBackupScheduleRequest, dict]] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> schedule.BackupSchedule: + r"""Gets information about a backup schedule. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import firestore_admin_v1 + + async def sample_get_backup_schedule(): + # Create a client + client = firestore_admin_v1.FirestoreAdminAsyncClient() + + # Initialize request argument(s) + request = firestore_admin_v1.GetBackupScheduleRequest( + name="name_value", + ) + + # Make the request + response = await client.get_backup_schedule(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.firestore_admin_v1.types.GetBackupScheduleRequest, dict]]): + The request object. The request for + [FirestoreAdmin.GetBackupSchedule][google.firestore.admin.v1.FirestoreAdmin.GetBackupSchedule]. + name (:class:`str`): + Required. The name of the backup schedule. + + Format + ``projects/{project}/databases/{database}/backupSchedules/{backup_schedule}`` + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.firestore_admin_v1.types.BackupSchedule: + A backup schedule for a Cloud + Firestore Database. + This resource is owned by the database + it is backing up, and is deleted along + with the database. The actual backups + are not though. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = firestore_admin.GetBackupScheduleRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.get_backup_schedule, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def list_backup_schedules( + self, + request: Optional[ + Union[firestore_admin.ListBackupSchedulesRequest, dict] + ] = None, + *, + parent: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> firestore_admin.ListBackupSchedulesResponse: + r"""List backup schedules. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import firestore_admin_v1 + + async def sample_list_backup_schedules(): + # Create a client + client = firestore_admin_v1.FirestoreAdminAsyncClient() + + # Initialize request argument(s) + request = firestore_admin_v1.ListBackupSchedulesRequest( + parent="parent_value", + ) + + # Make the request + response = await client.list_backup_schedules(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.firestore_admin_v1.types.ListBackupSchedulesRequest, dict]]): + The request object. The request for + [FirestoreAdmin.ListBackupSchedules][google.firestore.admin.v1.FirestoreAdmin.ListBackupSchedules]. + parent (:class:`str`): + Required. The parent database. + + Format is ``projects/{project}/databases/{database}``. + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.firestore_admin_v1.types.ListBackupSchedulesResponse: + The response for + [FirestoreAdmin.ListBackupSchedules][google.firestore.admin.v1.FirestoreAdmin.ListBackupSchedules]. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = firestore_admin.ListBackupSchedulesRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.list_backup_schedules, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def update_backup_schedule( + self, + request: Optional[ + Union[firestore_admin.UpdateBackupScheduleRequest, dict] + ] = None, + *, + backup_schedule: Optional[schedule.BackupSchedule] = None, + update_mask: Optional[field_mask_pb2.FieldMask] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> schedule.BackupSchedule: + r"""Updates a backup schedule. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import firestore_admin_v1 + + async def sample_update_backup_schedule(): + # Create a client + client = firestore_admin_v1.FirestoreAdminAsyncClient() + + # Initialize request argument(s) + request = firestore_admin_v1.UpdateBackupScheduleRequest( + ) + + # Make the request + response = await client.update_backup_schedule(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.firestore_admin_v1.types.UpdateBackupScheduleRequest, dict]]): + The request object. The request for + [FirestoreAdmin.UpdateBackupSchedule][google.firestore.admin.v1.FirestoreAdmin.UpdateBackupSchedule]. + backup_schedule (:class:`google.cloud.firestore_admin_v1.types.BackupSchedule`): + Required. The backup schedule to + update. + + This corresponds to the ``backup_schedule`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + update_mask (:class:`google.protobuf.field_mask_pb2.FieldMask`): + The list of fields to be updated. + This corresponds to the ``update_mask`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.firestore_admin_v1.types.BackupSchedule: + A backup schedule for a Cloud + Firestore Database. + This resource is owned by the database + it is backing up, and is deleted along + with the database. The actual backups + are not though. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([backup_schedule, update_mask]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = firestore_admin.UpdateBackupScheduleRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if backup_schedule is not None: + request.backup_schedule = backup_schedule + if update_mask is not None: + request.update_mask = update_mask + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.update_backup_schedule, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("backup_schedule.name", request.backup_schedule.name),) + ), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def delete_backup_schedule( + self, + request: Optional[ + Union[firestore_admin.DeleteBackupScheduleRequest, dict] + ] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> None: + r"""Deletes a backup schedule. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import firestore_admin_v1 + + async def sample_delete_backup_schedule(): + # Create a client + client = firestore_admin_v1.FirestoreAdminAsyncClient() + + # Initialize request argument(s) + request = firestore_admin_v1.DeleteBackupScheduleRequest( + name="name_value", + ) + + # Make the request + await client.delete_backup_schedule(request=request) + + Args: + request (Optional[Union[google.cloud.firestore_admin_v1.types.DeleteBackupScheduleRequest, dict]]): + The request object. The request for + [FirestoreAdmin.DeleteBackupSchedules][]. + name (:class:`str`): + Required. The name of backup schedule. + + Format + ``projects/{project}/databases/{database}/backupSchedules/{backup_schedule}`` + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry_async.AsyncRetry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + request = firestore_admin.DeleteBackupScheduleRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.delete_backup_schedule, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._client._validate_universe_domain() + + # Send the request. + await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + async def list_operations( self, request: Optional[operations_pb2.ListOperationsRequest] = None, diff --git a/google/cloud/firestore_admin_v1/services/firestore_admin/client.py b/google/cloud/firestore_admin_v1/services/firestore_admin/client.py index b0b489c71..e9a45904d 100644 --- a/google/cloud/firestore_admin_v1/services/firestore_admin/client.py +++ b/google/cloud/firestore_admin_v1/services/firestore_admin/client.py @@ -50,6 +50,7 @@ from google.api_core import operation as gac_operation # type: ignore from google.api_core import operation_async # type: ignore from google.cloud.firestore_admin_v1.services.firestore_admin import pagers +from google.cloud.firestore_admin_v1.types import backup from google.cloud.firestore_admin_v1.types import database from google.cloud.firestore_admin_v1.types import database as gfa_database from google.cloud.firestore_admin_v1.types import field @@ -58,6 +59,7 @@ from google.cloud.firestore_admin_v1.types import index from google.cloud.firestore_admin_v1.types import index as gfa_index from google.cloud.firestore_admin_v1.types import operation as gfa_operation +from google.cloud.firestore_admin_v1.types import schedule from google.cloud.location import locations_pb2 # type: ignore from google.longrunning import operations_pb2 # type: ignore from google.protobuf import duration_pb2 # type: ignore @@ -227,6 +229,50 @@ def transport(self) -> FirestoreAdminTransport: """ return self._transport + @staticmethod + def backup_path( + project: str, + location: str, + backup: str, + ) -> str: + """Returns a fully-qualified backup string.""" + return "projects/{project}/locations/{location}/backups/{backup}".format( + project=project, + location=location, + backup=backup, + ) + + @staticmethod + def parse_backup_path(path: str) -> Dict[str, str]: + """Parses a backup path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/locations/(?P.+?)/backups/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + + @staticmethod + def backup_schedule_path( + project: str, + database: str, + backup_schedule: str, + ) -> str: + """Returns a fully-qualified backup_schedule string.""" + return "projects/{project}/databases/{database}/backupSchedules/{backup_schedule}".format( + project=project, + database=database, + backup_schedule=backup_schedule, + ) + + @staticmethod + def parse_backup_schedule_path(path: str) -> Dict[str, str]: + """Parses a backup_schedule path into its component segments.""" + m = re.match( + r"^projects/(?P.+?)/databases/(?P.+?)/backupSchedules/(?P.+?)$", + path, + ) + return m.groupdict() if m else {} + @staticmethod def collection_group_path( project: str, @@ -314,6 +360,23 @@ def parse_index_path(path: str) -> Dict[str, str]: ) return m.groupdict() if m else {} + @staticmethod + def location_path( + project: str, + location: str, + ) -> str: + """Returns a fully-qualified location string.""" + return "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + + @staticmethod + def parse_location_path(path: str) -> Dict[str, str]: + """Parses a location path into its component segments.""" + m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)$", path) + return m.groupdict() if m else {} + @staticmethod def common_billing_account_path( billing_account: str, @@ -2468,6 +2531,1001 @@ def sample_delete_database(): # Done; return the response. return response + def get_backup( + self, + request: Optional[Union[firestore_admin.GetBackupRequest, dict]] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> backup.Backup: + r"""Gets information about a backup. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import firestore_admin_v1 + + def sample_get_backup(): + # Create a client + client = firestore_admin_v1.FirestoreAdminClient() + + # Initialize request argument(s) + request = firestore_admin_v1.GetBackupRequest( + name="name_value", + ) + + # Make the request + response = client.get_backup(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.firestore_admin_v1.types.GetBackupRequest, dict]): + The request object. The request for + [FirestoreAdmin.GetBackup][google.firestore.admin.v1.FirestoreAdmin.GetBackup]. + name (str): + Required. Name of the backup to fetch. + + Format is + ``projects/{project}/locations/{location}/backups/{backup}``. + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.firestore_admin_v1.types.Backup: + A Backup of a Cloud Firestore + Database. + The backup contains all documents and + index configurations for the given + database at a specific point in time. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a firestore_admin.GetBackupRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, firestore_admin.GetBackupRequest): + request = firestore_admin.GetBackupRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.get_backup] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def list_backups( + self, + request: Optional[Union[firestore_admin.ListBackupsRequest, dict]] = None, + *, + parent: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> firestore_admin.ListBackupsResponse: + r"""Lists all the backups. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import firestore_admin_v1 + + def sample_list_backups(): + # Create a client + client = firestore_admin_v1.FirestoreAdminClient() + + # Initialize request argument(s) + request = firestore_admin_v1.ListBackupsRequest( + parent="parent_value", + ) + + # Make the request + response = client.list_backups(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.firestore_admin_v1.types.ListBackupsRequest, dict]): + The request object. The request for + [FirestoreAdmin.ListBackups][google.firestore.admin.v1.FirestoreAdmin.ListBackups]. + parent (str): + Required. The location to list backups from. + + Format is ``projects/{project}/locations/{location}``. + Use ``{location} = '-'`` to list backups from all + locations for the given project. This allows listing + backups from a single location or from all locations. + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.firestore_admin_v1.types.ListBackupsResponse: + The response for + [FirestoreAdmin.ListBackups][google.firestore.admin.v1.FirestoreAdmin.ListBackups]. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a firestore_admin.ListBackupsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, firestore_admin.ListBackupsRequest): + request = firestore_admin.ListBackupsRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.list_backups] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def delete_backup( + self, + request: Optional[Union[firestore_admin.DeleteBackupRequest, dict]] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> None: + r"""Deletes a backup. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import firestore_admin_v1 + + def sample_delete_backup(): + # Create a client + client = firestore_admin_v1.FirestoreAdminClient() + + # Initialize request argument(s) + request = firestore_admin_v1.DeleteBackupRequest( + name="name_value", + ) + + # Make the request + client.delete_backup(request=request) + + Args: + request (Union[google.cloud.firestore_admin_v1.types.DeleteBackupRequest, dict]): + The request object. The request for + [FirestoreAdmin.DeleteBackup][google.firestore.admin.v1.FirestoreAdmin.DeleteBackup]. + name (str): + Required. Name of the backup to delete. + + format is + ``projects/{project}/locations/{location}/backups/{backup}``. + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a firestore_admin.DeleteBackupRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, firestore_admin.DeleteBackupRequest): + request = firestore_admin.DeleteBackupRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.delete_backup] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + def restore_database( + self, + request: Optional[Union[firestore_admin.RestoreDatabaseRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> gac_operation.Operation: + r"""Creates a new database by restoring from an existing backup. + + The new database must be in the same cloud region or + multi-region location as the existing backup. This behaves + similar to + [FirestoreAdmin.CreateDatabase][google.firestore.admin.v1.CreateDatabase] + except instead of creating a new empty database, a new database + is created with the database type, index configuration, and + documents from an existing backup. + + The [long-running operation][google.longrunning.Operation] can + be used to track the progress of the restore, with the + Operation's [metadata][google.longrunning.Operation.metadata] + field type being the + [RestoreDatabaseMetadata][google.firestore.admin.v1.RestoreDatabaseMetadata]. + The [response][google.longrunning.Operation.response] type is + the [Database][google.firestore.admin.v1.Database] if the + restore was successful. The new database is not readable or + writeable until the LRO has completed. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import firestore_admin_v1 + + def sample_restore_database(): + # Create a client + client = firestore_admin_v1.FirestoreAdminClient() + + # Initialize request argument(s) + request = firestore_admin_v1.RestoreDatabaseRequest( + parent="parent_value", + database_id="database_id_value", + backup="backup_value", + ) + + # Make the request + operation = client.restore_database(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.firestore_admin_v1.types.RestoreDatabaseRequest, dict]): + The request object. The request message for + [FirestoreAdmin.RestoreDatabase][google.firestore.admin.v1.RestoreDatabase]. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.api_core.operation.Operation: + An object representing a long-running operation. + + The result type for the operation will be + :class:`google.cloud.firestore_admin_v1.types.Database` + A Cloud Firestore Database. + + """ + # Create or coerce a protobuf request object. + # Minor optimization to avoid making a copy if the user passes + # in a firestore_admin.RestoreDatabaseRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, firestore_admin.RestoreDatabaseRequest): + request = firestore_admin.RestoreDatabaseRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.restore_database] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Wrap the response in an operation future. + response = gac_operation.from_gapic( + response, + self._transport.operations_client, + database.Database, + metadata_type=gfa_operation.RestoreDatabaseMetadata, + ) + + # Done; return the response. + return response + + def create_backup_schedule( + self, + request: Optional[ + Union[firestore_admin.CreateBackupScheduleRequest, dict] + ] = None, + *, + parent: Optional[str] = None, + backup_schedule: Optional[schedule.BackupSchedule] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> schedule.BackupSchedule: + r"""Creates a backup schedule on a database. + At most two backup schedules can be configured on a + database, one daily backup schedule with retention up to + 7 days and one weekly backup schedule with retention up + to 14 weeks. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import firestore_admin_v1 + + def sample_create_backup_schedule(): + # Create a client + client = firestore_admin_v1.FirestoreAdminClient() + + # Initialize request argument(s) + request = firestore_admin_v1.CreateBackupScheduleRequest( + parent="parent_value", + ) + + # Make the request + response = client.create_backup_schedule(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.firestore_admin_v1.types.CreateBackupScheduleRequest, dict]): + The request object. The request for + [FirestoreAdmin.CreateBackupSchedule][google.firestore.admin.v1.FirestoreAdmin.CreateBackupSchedule]. + parent (str): + Required. The parent database. + + Format ``projects/{project}/databases/{database}`` + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + backup_schedule (google.cloud.firestore_admin_v1.types.BackupSchedule): + Required. The backup schedule to + create. + + This corresponds to the ``backup_schedule`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.firestore_admin_v1.types.BackupSchedule: + A backup schedule for a Cloud + Firestore Database. + This resource is owned by the database + it is backing up, and is deleted along + with the database. The actual backups + are not though. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent, backup_schedule]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a firestore_admin.CreateBackupScheduleRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, firestore_admin.CreateBackupScheduleRequest): + request = firestore_admin.CreateBackupScheduleRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if backup_schedule is not None: + request.backup_schedule = backup_schedule + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.create_backup_schedule] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def get_backup_schedule( + self, + request: Optional[Union[firestore_admin.GetBackupScheduleRequest, dict]] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> schedule.BackupSchedule: + r"""Gets information about a backup schedule. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import firestore_admin_v1 + + def sample_get_backup_schedule(): + # Create a client + client = firestore_admin_v1.FirestoreAdminClient() + + # Initialize request argument(s) + request = firestore_admin_v1.GetBackupScheduleRequest( + name="name_value", + ) + + # Make the request + response = client.get_backup_schedule(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.firestore_admin_v1.types.GetBackupScheduleRequest, dict]): + The request object. The request for + [FirestoreAdmin.GetBackupSchedule][google.firestore.admin.v1.FirestoreAdmin.GetBackupSchedule]. + name (str): + Required. The name of the backup schedule. + + Format + ``projects/{project}/databases/{database}/backupSchedules/{backup_schedule}`` + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.firestore_admin_v1.types.BackupSchedule: + A backup schedule for a Cloud + Firestore Database. + This resource is owned by the database + it is backing up, and is deleted along + with the database. The actual backups + are not though. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a firestore_admin.GetBackupScheduleRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, firestore_admin.GetBackupScheduleRequest): + request = firestore_admin.GetBackupScheduleRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.get_backup_schedule] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def list_backup_schedules( + self, + request: Optional[ + Union[firestore_admin.ListBackupSchedulesRequest, dict] + ] = None, + *, + parent: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> firestore_admin.ListBackupSchedulesResponse: + r"""List backup schedules. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import firestore_admin_v1 + + def sample_list_backup_schedules(): + # Create a client + client = firestore_admin_v1.FirestoreAdminClient() + + # Initialize request argument(s) + request = firestore_admin_v1.ListBackupSchedulesRequest( + parent="parent_value", + ) + + # Make the request + response = client.list_backup_schedules(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.firestore_admin_v1.types.ListBackupSchedulesRequest, dict]): + The request object. The request for + [FirestoreAdmin.ListBackupSchedules][google.firestore.admin.v1.FirestoreAdmin.ListBackupSchedules]. + parent (str): + Required. The parent database. + + Format is ``projects/{project}/databases/{database}``. + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.firestore_admin_v1.types.ListBackupSchedulesResponse: + The response for + [FirestoreAdmin.ListBackupSchedules][google.firestore.admin.v1.FirestoreAdmin.ListBackupSchedules]. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([parent]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a firestore_admin.ListBackupSchedulesRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, firestore_admin.ListBackupSchedulesRequest): + request = firestore_admin.ListBackupSchedulesRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.list_backup_schedules] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def update_backup_schedule( + self, + request: Optional[ + Union[firestore_admin.UpdateBackupScheduleRequest, dict] + ] = None, + *, + backup_schedule: Optional[schedule.BackupSchedule] = None, + update_mask: Optional[field_mask_pb2.FieldMask] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> schedule.BackupSchedule: + r"""Updates a backup schedule. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import firestore_admin_v1 + + def sample_update_backup_schedule(): + # Create a client + client = firestore_admin_v1.FirestoreAdminClient() + + # Initialize request argument(s) + request = firestore_admin_v1.UpdateBackupScheduleRequest( + ) + + # Make the request + response = client.update_backup_schedule(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.firestore_admin_v1.types.UpdateBackupScheduleRequest, dict]): + The request object. The request for + [FirestoreAdmin.UpdateBackupSchedule][google.firestore.admin.v1.FirestoreAdmin.UpdateBackupSchedule]. + backup_schedule (google.cloud.firestore_admin_v1.types.BackupSchedule): + Required. The backup schedule to + update. + + This corresponds to the ``backup_schedule`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + The list of fields to be updated. + This corresponds to the ``update_mask`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.cloud.firestore_admin_v1.types.BackupSchedule: + A backup schedule for a Cloud + Firestore Database. + This resource is owned by the database + it is backing up, and is deleted along + with the database. The actual backups + are not though. + + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([backup_schedule, update_mask]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a firestore_admin.UpdateBackupScheduleRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, firestore_admin.UpdateBackupScheduleRequest): + request = firestore_admin.UpdateBackupScheduleRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if backup_schedule is not None: + request.backup_schedule = backup_schedule + if update_mask is not None: + request.update_mask = update_mask + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.update_backup_schedule] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata( + (("backup_schedule.name", request.backup_schedule.name),) + ), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def delete_backup_schedule( + self, + request: Optional[ + Union[firestore_admin.DeleteBackupScheduleRequest, dict] + ] = None, + *, + name: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> None: + r"""Deletes a backup schedule. + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import firestore_admin_v1 + + def sample_delete_backup_schedule(): + # Create a client + client = firestore_admin_v1.FirestoreAdminClient() + + # Initialize request argument(s) + request = firestore_admin_v1.DeleteBackupScheduleRequest( + name="name_value", + ) + + # Make the request + client.delete_backup_schedule(request=request) + + Args: + request (Union[google.cloud.firestore_admin_v1.types.DeleteBackupScheduleRequest, dict]): + The request object. The request for + [FirestoreAdmin.DeleteBackupSchedules][]. + name (str): + Required. The name of backup schedule. + + Format + ``projects/{project}/databases/{database}/backupSchedules/{backup_schedule}`` + + This corresponds to the ``name`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + # Create or coerce a protobuf request object. + # Quick check: If we got a request object, we should *not* have + # gotten any keyword arguments that map to the request. + has_flattened_params = any([name]) + if request is not None and has_flattened_params: + raise ValueError( + "If the `request` argument is set, then none of " + "the individual field arguments should be set." + ) + + # Minor optimization to avoid making a copy if the user passes + # in a firestore_admin.DeleteBackupScheduleRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, firestore_admin.DeleteBackupScheduleRequest): + request = firestore_admin.DeleteBackupScheduleRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if name is not None: + request.name = name + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.delete_backup_schedule] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("name", request.name),)), + ) + + # Validate the universe domain. + self._validate_universe_domain() + + # Send the request. + rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + def __enter__(self) -> "FirestoreAdminClient": return self diff --git a/google/cloud/firestore_admin_v1/services/firestore_admin/transports/base.py b/google/cloud/firestore_admin_v1/services/firestore_admin/transports/base.py index ce4848309..9ebcdad6f 100644 --- a/google/cloud/firestore_admin_v1/services/firestore_admin/transports/base.py +++ b/google/cloud/firestore_admin_v1/services/firestore_admin/transports/base.py @@ -27,10 +27,12 @@ from google.auth import credentials as ga_credentials # type: ignore from google.oauth2 import service_account # type: ignore +from google.cloud.firestore_admin_v1.types import backup from google.cloud.firestore_admin_v1.types import database from google.cloud.firestore_admin_v1.types import field from google.cloud.firestore_admin_v1.types import firestore_admin from google.cloud.firestore_admin_v1.types import index +from google.cloud.firestore_admin_v1.types import schedule from google.cloud.location import locations_pb2 # type: ignore from google.longrunning import operations_pb2 # type: ignore from google.protobuf import empty_pb2 # type: ignore @@ -262,6 +264,51 @@ def _prep_wrapped_messages(self, client_info): default_timeout=None, client_info=client_info, ), + self.get_backup: gapic_v1.method.wrap_method( + self.get_backup, + default_timeout=None, + client_info=client_info, + ), + self.list_backups: gapic_v1.method.wrap_method( + self.list_backups, + default_timeout=None, + client_info=client_info, + ), + self.delete_backup: gapic_v1.method.wrap_method( + self.delete_backup, + default_timeout=None, + client_info=client_info, + ), + self.restore_database: gapic_v1.method.wrap_method( + self.restore_database, + default_timeout=None, + client_info=client_info, + ), + self.create_backup_schedule: gapic_v1.method.wrap_method( + self.create_backup_schedule, + default_timeout=None, + client_info=client_info, + ), + self.get_backup_schedule: gapic_v1.method.wrap_method( + self.get_backup_schedule, + default_timeout=None, + client_info=client_info, + ), + self.list_backup_schedules: gapic_v1.method.wrap_method( + self.list_backup_schedules, + default_timeout=None, + client_info=client_info, + ), + self.update_backup_schedule: gapic_v1.method.wrap_method( + self.update_backup_schedule, + default_timeout=None, + client_info=client_info, + ), + self.delete_backup_schedule: gapic_v1.method.wrap_method( + self.delete_backup_schedule, + default_timeout=None, + client_info=client_info, + ), } def close(self): @@ -411,6 +458,93 @@ def delete_database( ]: raise NotImplementedError() + @property + def get_backup( + self, + ) -> Callable[ + [firestore_admin.GetBackupRequest], + Union[backup.Backup, Awaitable[backup.Backup]], + ]: + raise NotImplementedError() + + @property + def list_backups( + self, + ) -> Callable[ + [firestore_admin.ListBackupsRequest], + Union[ + firestore_admin.ListBackupsResponse, + Awaitable[firestore_admin.ListBackupsResponse], + ], + ]: + raise NotImplementedError() + + @property + def delete_backup( + self, + ) -> Callable[ + [firestore_admin.DeleteBackupRequest], + Union[empty_pb2.Empty, Awaitable[empty_pb2.Empty]], + ]: + raise NotImplementedError() + + @property + def restore_database( + self, + ) -> Callable[ + [firestore_admin.RestoreDatabaseRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + + @property + def create_backup_schedule( + self, + ) -> Callable[ + [firestore_admin.CreateBackupScheduleRequest], + Union[schedule.BackupSchedule, Awaitable[schedule.BackupSchedule]], + ]: + raise NotImplementedError() + + @property + def get_backup_schedule( + self, + ) -> Callable[ + [firestore_admin.GetBackupScheduleRequest], + Union[schedule.BackupSchedule, Awaitable[schedule.BackupSchedule]], + ]: + raise NotImplementedError() + + @property + def list_backup_schedules( + self, + ) -> Callable[ + [firestore_admin.ListBackupSchedulesRequest], + Union[ + firestore_admin.ListBackupSchedulesResponse, + Awaitable[firestore_admin.ListBackupSchedulesResponse], + ], + ]: + raise NotImplementedError() + + @property + def update_backup_schedule( + self, + ) -> Callable[ + [firestore_admin.UpdateBackupScheduleRequest], + Union[schedule.BackupSchedule, Awaitable[schedule.BackupSchedule]], + ]: + raise NotImplementedError() + + @property + def delete_backup_schedule( + self, + ) -> Callable[ + [firestore_admin.DeleteBackupScheduleRequest], + Union[empty_pb2.Empty, Awaitable[empty_pb2.Empty]], + ]: + raise NotImplementedError() + @property def list_operations( self, diff --git a/google/cloud/firestore_admin_v1/services/firestore_admin/transports/grpc.py b/google/cloud/firestore_admin_v1/services/firestore_admin/transports/grpc.py index 09198f948..f06ca83bd 100644 --- a/google/cloud/firestore_admin_v1/services/firestore_admin/transports/grpc.py +++ b/google/cloud/firestore_admin_v1/services/firestore_admin/transports/grpc.py @@ -25,10 +25,12 @@ import grpc # type: ignore +from google.cloud.firestore_admin_v1.types import backup from google.cloud.firestore_admin_v1.types import database from google.cloud.firestore_admin_v1.types import field from google.cloud.firestore_admin_v1.types import firestore_admin from google.cloud.firestore_admin_v1.types import index +from google.cloud.firestore_admin_v1.types import schedule from google.cloud.location import locations_pb2 # type: ignore from google.longrunning import operations_pb2 # type: ignore from google.protobuf import empty_pb2 # type: ignore @@ -694,6 +696,269 @@ def delete_database( ) return self._stubs["delete_database"] + @property + def get_backup(self) -> Callable[[firestore_admin.GetBackupRequest], backup.Backup]: + r"""Return a callable for the get backup method over gRPC. + + Gets information about a backup. + + Returns: + Callable[[~.GetBackupRequest], + ~.Backup]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "get_backup" not in self._stubs: + self._stubs["get_backup"] = self.grpc_channel.unary_unary( + "/google.firestore.admin.v1.FirestoreAdmin/GetBackup", + request_serializer=firestore_admin.GetBackupRequest.serialize, + response_deserializer=backup.Backup.deserialize, + ) + return self._stubs["get_backup"] + + @property + def list_backups( + self, + ) -> Callable[ + [firestore_admin.ListBackupsRequest], firestore_admin.ListBackupsResponse + ]: + r"""Return a callable for the list backups method over gRPC. + + Lists all the backups. + + Returns: + Callable[[~.ListBackupsRequest], + ~.ListBackupsResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "list_backups" not in self._stubs: + self._stubs["list_backups"] = self.grpc_channel.unary_unary( + "/google.firestore.admin.v1.FirestoreAdmin/ListBackups", + request_serializer=firestore_admin.ListBackupsRequest.serialize, + response_deserializer=firestore_admin.ListBackupsResponse.deserialize, + ) + return self._stubs["list_backups"] + + @property + def delete_backup( + self, + ) -> Callable[[firestore_admin.DeleteBackupRequest], empty_pb2.Empty]: + r"""Return a callable for the delete backup method over gRPC. + + Deletes a backup. + + Returns: + Callable[[~.DeleteBackupRequest], + ~.Empty]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "delete_backup" not in self._stubs: + self._stubs["delete_backup"] = self.grpc_channel.unary_unary( + "/google.firestore.admin.v1.FirestoreAdmin/DeleteBackup", + request_serializer=firestore_admin.DeleteBackupRequest.serialize, + response_deserializer=empty_pb2.Empty.FromString, + ) + return self._stubs["delete_backup"] + + @property + def restore_database( + self, + ) -> Callable[[firestore_admin.RestoreDatabaseRequest], operations_pb2.Operation]: + r"""Return a callable for the restore database method over gRPC. + + Creates a new database by restoring from an existing backup. + + The new database must be in the same cloud region or + multi-region location as the existing backup. This behaves + similar to + [FirestoreAdmin.CreateDatabase][google.firestore.admin.v1.CreateDatabase] + except instead of creating a new empty database, a new database + is created with the database type, index configuration, and + documents from an existing backup. + + The [long-running operation][google.longrunning.Operation] can + be used to track the progress of the restore, with the + Operation's [metadata][google.longrunning.Operation.metadata] + field type being the + [RestoreDatabaseMetadata][google.firestore.admin.v1.RestoreDatabaseMetadata]. + The [response][google.longrunning.Operation.response] type is + the [Database][google.firestore.admin.v1.Database] if the + restore was successful. The new database is not readable or + writeable until the LRO has completed. + + Returns: + Callable[[~.RestoreDatabaseRequest], + ~.Operation]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "restore_database" not in self._stubs: + self._stubs["restore_database"] = self.grpc_channel.unary_unary( + "/google.firestore.admin.v1.FirestoreAdmin/RestoreDatabase", + request_serializer=firestore_admin.RestoreDatabaseRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["restore_database"] + + @property + def create_backup_schedule( + self, + ) -> Callable[ + [firestore_admin.CreateBackupScheduleRequest], schedule.BackupSchedule + ]: + r"""Return a callable for the create backup schedule method over gRPC. + + Creates a backup schedule on a database. + At most two backup schedules can be configured on a + database, one daily backup schedule with retention up to + 7 days and one weekly backup schedule with retention up + to 14 weeks. + + Returns: + Callable[[~.CreateBackupScheduleRequest], + ~.BackupSchedule]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "create_backup_schedule" not in self._stubs: + self._stubs["create_backup_schedule"] = self.grpc_channel.unary_unary( + "/google.firestore.admin.v1.FirestoreAdmin/CreateBackupSchedule", + request_serializer=firestore_admin.CreateBackupScheduleRequest.serialize, + response_deserializer=schedule.BackupSchedule.deserialize, + ) + return self._stubs["create_backup_schedule"] + + @property + def get_backup_schedule( + self, + ) -> Callable[[firestore_admin.GetBackupScheduleRequest], schedule.BackupSchedule]: + r"""Return a callable for the get backup schedule method over gRPC. + + Gets information about a backup schedule. + + Returns: + Callable[[~.GetBackupScheduleRequest], + ~.BackupSchedule]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "get_backup_schedule" not in self._stubs: + self._stubs["get_backup_schedule"] = self.grpc_channel.unary_unary( + "/google.firestore.admin.v1.FirestoreAdmin/GetBackupSchedule", + request_serializer=firestore_admin.GetBackupScheduleRequest.serialize, + response_deserializer=schedule.BackupSchedule.deserialize, + ) + return self._stubs["get_backup_schedule"] + + @property + def list_backup_schedules( + self, + ) -> Callable[ + [firestore_admin.ListBackupSchedulesRequest], + firestore_admin.ListBackupSchedulesResponse, + ]: + r"""Return a callable for the list backup schedules method over gRPC. + + List backup schedules. + + Returns: + Callable[[~.ListBackupSchedulesRequest], + ~.ListBackupSchedulesResponse]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "list_backup_schedules" not in self._stubs: + self._stubs["list_backup_schedules"] = self.grpc_channel.unary_unary( + "/google.firestore.admin.v1.FirestoreAdmin/ListBackupSchedules", + request_serializer=firestore_admin.ListBackupSchedulesRequest.serialize, + response_deserializer=firestore_admin.ListBackupSchedulesResponse.deserialize, + ) + return self._stubs["list_backup_schedules"] + + @property + def update_backup_schedule( + self, + ) -> Callable[ + [firestore_admin.UpdateBackupScheduleRequest], schedule.BackupSchedule + ]: + r"""Return a callable for the update backup schedule method over gRPC. + + Updates a backup schedule. + + Returns: + Callable[[~.UpdateBackupScheduleRequest], + ~.BackupSchedule]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "update_backup_schedule" not in self._stubs: + self._stubs["update_backup_schedule"] = self.grpc_channel.unary_unary( + "/google.firestore.admin.v1.FirestoreAdmin/UpdateBackupSchedule", + request_serializer=firestore_admin.UpdateBackupScheduleRequest.serialize, + response_deserializer=schedule.BackupSchedule.deserialize, + ) + return self._stubs["update_backup_schedule"] + + @property + def delete_backup_schedule( + self, + ) -> Callable[[firestore_admin.DeleteBackupScheduleRequest], empty_pb2.Empty]: + r"""Return a callable for the delete backup schedule method over gRPC. + + Deletes a backup schedule. + + Returns: + Callable[[~.DeleteBackupScheduleRequest], + ~.Empty]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "delete_backup_schedule" not in self._stubs: + self._stubs["delete_backup_schedule"] = self.grpc_channel.unary_unary( + "/google.firestore.admin.v1.FirestoreAdmin/DeleteBackupSchedule", + request_serializer=firestore_admin.DeleteBackupScheduleRequest.serialize, + response_deserializer=empty_pb2.Empty.FromString, + ) + return self._stubs["delete_backup_schedule"] + def close(self): self.grpc_channel.close() diff --git a/google/cloud/firestore_admin_v1/services/firestore_admin/transports/grpc_asyncio.py b/google/cloud/firestore_admin_v1/services/firestore_admin/transports/grpc_asyncio.py index 620a6b2de..78c18a043 100644 --- a/google/cloud/firestore_admin_v1/services/firestore_admin/transports/grpc_asyncio.py +++ b/google/cloud/firestore_admin_v1/services/firestore_admin/transports/grpc_asyncio.py @@ -25,10 +25,12 @@ import grpc # type: ignore from grpc.experimental import aio # type: ignore +from google.cloud.firestore_admin_v1.types import backup from google.cloud.firestore_admin_v1.types import database from google.cloud.firestore_admin_v1.types import field from google.cloud.firestore_admin_v1.types import firestore_admin from google.cloud.firestore_admin_v1.types import index +from google.cloud.firestore_admin_v1.types import schedule from google.cloud.location import locations_pb2 # type: ignore from google.longrunning import operations_pb2 # type: ignore from google.protobuf import empty_pb2 # type: ignore @@ -720,6 +722,280 @@ def delete_database( ) return self._stubs["delete_database"] + @property + def get_backup( + self, + ) -> Callable[[firestore_admin.GetBackupRequest], Awaitable[backup.Backup]]: + r"""Return a callable for the get backup method over gRPC. + + Gets information about a backup. + + Returns: + Callable[[~.GetBackupRequest], + Awaitable[~.Backup]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "get_backup" not in self._stubs: + self._stubs["get_backup"] = self.grpc_channel.unary_unary( + "/google.firestore.admin.v1.FirestoreAdmin/GetBackup", + request_serializer=firestore_admin.GetBackupRequest.serialize, + response_deserializer=backup.Backup.deserialize, + ) + return self._stubs["get_backup"] + + @property + def list_backups( + self, + ) -> Callable[ + [firestore_admin.ListBackupsRequest], + Awaitable[firestore_admin.ListBackupsResponse], + ]: + r"""Return a callable for the list backups method over gRPC. + + Lists all the backups. + + Returns: + Callable[[~.ListBackupsRequest], + Awaitable[~.ListBackupsResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "list_backups" not in self._stubs: + self._stubs["list_backups"] = self.grpc_channel.unary_unary( + "/google.firestore.admin.v1.FirestoreAdmin/ListBackups", + request_serializer=firestore_admin.ListBackupsRequest.serialize, + response_deserializer=firestore_admin.ListBackupsResponse.deserialize, + ) + return self._stubs["list_backups"] + + @property + def delete_backup( + self, + ) -> Callable[[firestore_admin.DeleteBackupRequest], Awaitable[empty_pb2.Empty]]: + r"""Return a callable for the delete backup method over gRPC. + + Deletes a backup. + + Returns: + Callable[[~.DeleteBackupRequest], + Awaitable[~.Empty]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "delete_backup" not in self._stubs: + self._stubs["delete_backup"] = self.grpc_channel.unary_unary( + "/google.firestore.admin.v1.FirestoreAdmin/DeleteBackup", + request_serializer=firestore_admin.DeleteBackupRequest.serialize, + response_deserializer=empty_pb2.Empty.FromString, + ) + return self._stubs["delete_backup"] + + @property + def restore_database( + self, + ) -> Callable[ + [firestore_admin.RestoreDatabaseRequest], Awaitable[operations_pb2.Operation] + ]: + r"""Return a callable for the restore database method over gRPC. + + Creates a new database by restoring from an existing backup. + + The new database must be in the same cloud region or + multi-region location as the existing backup. This behaves + similar to + [FirestoreAdmin.CreateDatabase][google.firestore.admin.v1.CreateDatabase] + except instead of creating a new empty database, a new database + is created with the database type, index configuration, and + documents from an existing backup. + + The [long-running operation][google.longrunning.Operation] can + be used to track the progress of the restore, with the + Operation's [metadata][google.longrunning.Operation.metadata] + field type being the + [RestoreDatabaseMetadata][google.firestore.admin.v1.RestoreDatabaseMetadata]. + The [response][google.longrunning.Operation.response] type is + the [Database][google.firestore.admin.v1.Database] if the + restore was successful. The new database is not readable or + writeable until the LRO has completed. + + Returns: + Callable[[~.RestoreDatabaseRequest], + Awaitable[~.Operation]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "restore_database" not in self._stubs: + self._stubs["restore_database"] = self.grpc_channel.unary_unary( + "/google.firestore.admin.v1.FirestoreAdmin/RestoreDatabase", + request_serializer=firestore_admin.RestoreDatabaseRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["restore_database"] + + @property + def create_backup_schedule( + self, + ) -> Callable[ + [firestore_admin.CreateBackupScheduleRequest], + Awaitable[schedule.BackupSchedule], + ]: + r"""Return a callable for the create backup schedule method over gRPC. + + Creates a backup schedule on a database. + At most two backup schedules can be configured on a + database, one daily backup schedule with retention up to + 7 days and one weekly backup schedule with retention up + to 14 weeks. + + Returns: + Callable[[~.CreateBackupScheduleRequest], + Awaitable[~.BackupSchedule]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "create_backup_schedule" not in self._stubs: + self._stubs["create_backup_schedule"] = self.grpc_channel.unary_unary( + "/google.firestore.admin.v1.FirestoreAdmin/CreateBackupSchedule", + request_serializer=firestore_admin.CreateBackupScheduleRequest.serialize, + response_deserializer=schedule.BackupSchedule.deserialize, + ) + return self._stubs["create_backup_schedule"] + + @property + def get_backup_schedule( + self, + ) -> Callable[ + [firestore_admin.GetBackupScheduleRequest], Awaitable[schedule.BackupSchedule] + ]: + r"""Return a callable for the get backup schedule method over gRPC. + + Gets information about a backup schedule. + + Returns: + Callable[[~.GetBackupScheduleRequest], + Awaitable[~.BackupSchedule]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "get_backup_schedule" not in self._stubs: + self._stubs["get_backup_schedule"] = self.grpc_channel.unary_unary( + "/google.firestore.admin.v1.FirestoreAdmin/GetBackupSchedule", + request_serializer=firestore_admin.GetBackupScheduleRequest.serialize, + response_deserializer=schedule.BackupSchedule.deserialize, + ) + return self._stubs["get_backup_schedule"] + + @property + def list_backup_schedules( + self, + ) -> Callable[ + [firestore_admin.ListBackupSchedulesRequest], + Awaitable[firestore_admin.ListBackupSchedulesResponse], + ]: + r"""Return a callable for the list backup schedules method over gRPC. + + List backup schedules. + + Returns: + Callable[[~.ListBackupSchedulesRequest], + Awaitable[~.ListBackupSchedulesResponse]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "list_backup_schedules" not in self._stubs: + self._stubs["list_backup_schedules"] = self.grpc_channel.unary_unary( + "/google.firestore.admin.v1.FirestoreAdmin/ListBackupSchedules", + request_serializer=firestore_admin.ListBackupSchedulesRequest.serialize, + response_deserializer=firestore_admin.ListBackupSchedulesResponse.deserialize, + ) + return self._stubs["list_backup_schedules"] + + @property + def update_backup_schedule( + self, + ) -> Callable[ + [firestore_admin.UpdateBackupScheduleRequest], + Awaitable[schedule.BackupSchedule], + ]: + r"""Return a callable for the update backup schedule method over gRPC. + + Updates a backup schedule. + + Returns: + Callable[[~.UpdateBackupScheduleRequest], + Awaitable[~.BackupSchedule]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "update_backup_schedule" not in self._stubs: + self._stubs["update_backup_schedule"] = self.grpc_channel.unary_unary( + "/google.firestore.admin.v1.FirestoreAdmin/UpdateBackupSchedule", + request_serializer=firestore_admin.UpdateBackupScheduleRequest.serialize, + response_deserializer=schedule.BackupSchedule.deserialize, + ) + return self._stubs["update_backup_schedule"] + + @property + def delete_backup_schedule( + self, + ) -> Callable[ + [firestore_admin.DeleteBackupScheduleRequest], Awaitable[empty_pb2.Empty] + ]: + r"""Return a callable for the delete backup schedule method over gRPC. + + Deletes a backup schedule. + + Returns: + Callable[[~.DeleteBackupScheduleRequest], + Awaitable[~.Empty]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "delete_backup_schedule" not in self._stubs: + self._stubs["delete_backup_schedule"] = self.grpc_channel.unary_unary( + "/google.firestore.admin.v1.FirestoreAdmin/DeleteBackupSchedule", + request_serializer=firestore_admin.DeleteBackupScheduleRequest.serialize, + response_deserializer=empty_pb2.Empty.FromString, + ) + return self._stubs["delete_backup_schedule"] + def close(self): return self.grpc_channel.close() diff --git a/google/cloud/firestore_admin_v1/services/firestore_admin/transports/rest.py b/google/cloud/firestore_admin_v1/services/firestore_admin/transports/rest.py index 2f22b5c07..b77cce929 100644 --- a/google/cloud/firestore_admin_v1/services/firestore_admin/transports/rest.py +++ b/google/cloud/firestore_admin_v1/services/firestore_admin/transports/rest.py @@ -41,10 +41,12 @@ OptionalRetry = Union[retries.Retry, object, None] # type: ignore +from google.cloud.firestore_admin_v1.types import backup from google.cloud.firestore_admin_v1.types import database from google.cloud.firestore_admin_v1.types import field from google.cloud.firestore_admin_v1.types import firestore_admin from google.cloud.firestore_admin_v1.types import index +from google.cloud.firestore_admin_v1.types import schedule from google.protobuf import empty_pb2 # type: ignore from google.longrunning import operations_pb2 # type: ignore @@ -76,6 +78,14 @@ class FirestoreAdminRestInterceptor: .. code-block:: python class MyCustomFirestoreAdminInterceptor(FirestoreAdminRestInterceptor): + def pre_create_backup_schedule(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_create_backup_schedule(self, response): + logging.log(f"Received response: {response}") + return response + def pre_create_database(self, request, metadata): logging.log(f"Received request: {request}") return request, metadata @@ -92,6 +102,14 @@ def post_create_index(self, response): logging.log(f"Received response: {response}") return response + def pre_delete_backup(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def pre_delete_backup_schedule(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + def pre_delete_database(self, request, metadata): logging.log(f"Received request: {request}") return request, metadata @@ -112,6 +130,22 @@ def post_export_documents(self, response): logging.log(f"Received response: {response}") return response + def pre_get_backup(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_get_backup(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_get_backup_schedule(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_get_backup_schedule(self, response): + logging.log(f"Received response: {response}") + return response + def pre_get_database(self, request, metadata): logging.log(f"Received request: {request}") return request, metadata @@ -144,6 +178,22 @@ def post_import_documents(self, response): logging.log(f"Received response: {response}") return response + def pre_list_backups(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_list_backups(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_list_backup_schedules(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_list_backup_schedules(self, response): + logging.log(f"Received response: {response}") + return response + def pre_list_databases(self, request, metadata): logging.log(f"Received request: {request}") return request, metadata @@ -168,6 +218,22 @@ def post_list_indexes(self, response): logging.log(f"Received response: {response}") return response + def pre_restore_database(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_restore_database(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_update_backup_schedule(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_update_backup_schedule(self, response): + logging.log(f"Received response: {response}") + return response + def pre_update_database(self, request, metadata): logging.log(f"Received request: {request}") return request, metadata @@ -190,6 +256,29 @@ def post_update_field(self, response): """ + def pre_create_backup_schedule( + self, + request: firestore_admin.CreateBackupScheduleRequest, + metadata: Sequence[Tuple[str, str]], + ) -> Tuple[firestore_admin.CreateBackupScheduleRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for create_backup_schedule + + Override in a subclass to manipulate the request or metadata + before they are sent to the FirestoreAdmin server. + """ + return request, metadata + + def post_create_backup_schedule( + self, response: schedule.BackupSchedule + ) -> schedule.BackupSchedule: + """Post-rpc interceptor for create_backup_schedule + + Override in a subclass to manipulate the response + after it is returned by the FirestoreAdmin server but before + it is returned to user code. + """ + return response + def pre_create_database( self, request: firestore_admin.CreateDatabaseRequest, @@ -236,6 +325,30 @@ def post_create_index( """ return response + def pre_delete_backup( + self, + request: firestore_admin.DeleteBackupRequest, + metadata: Sequence[Tuple[str, str]], + ) -> Tuple[firestore_admin.DeleteBackupRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for delete_backup + + Override in a subclass to manipulate the request or metadata + before they are sent to the FirestoreAdmin server. + """ + return request, metadata + + def pre_delete_backup_schedule( + self, + request: firestore_admin.DeleteBackupScheduleRequest, + metadata: Sequence[Tuple[str, str]], + ) -> Tuple[firestore_admin.DeleteBackupScheduleRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for delete_backup_schedule + + Override in a subclass to manipulate the request or metadata + before they are sent to the FirestoreAdmin server. + """ + return request, metadata + def pre_delete_database( self, request: firestore_admin.DeleteDatabaseRequest, @@ -294,6 +407,50 @@ def post_export_documents( """ return response + def pre_get_backup( + self, + request: firestore_admin.GetBackupRequest, + metadata: Sequence[Tuple[str, str]], + ) -> Tuple[firestore_admin.GetBackupRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for get_backup + + Override in a subclass to manipulate the request or metadata + before they are sent to the FirestoreAdmin server. + """ + return request, metadata + + def post_get_backup(self, response: backup.Backup) -> backup.Backup: + """Post-rpc interceptor for get_backup + + Override in a subclass to manipulate the response + after it is returned by the FirestoreAdmin server but before + it is returned to user code. + """ + return response + + def pre_get_backup_schedule( + self, + request: firestore_admin.GetBackupScheduleRequest, + metadata: Sequence[Tuple[str, str]], + ) -> Tuple[firestore_admin.GetBackupScheduleRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for get_backup_schedule + + Override in a subclass to manipulate the request or metadata + before they are sent to the FirestoreAdmin server. + """ + return request, metadata + + def post_get_backup_schedule( + self, response: schedule.BackupSchedule + ) -> schedule.BackupSchedule: + """Post-rpc interceptor for get_backup_schedule + + Override in a subclass to manipulate the response + after it is returned by the FirestoreAdmin server but before + it is returned to user code. + """ + return response + def pre_get_database( self, request: firestore_admin.GetDatabaseRequest, @@ -380,6 +537,52 @@ def post_import_documents( """ return response + def pre_list_backups( + self, + request: firestore_admin.ListBackupsRequest, + metadata: Sequence[Tuple[str, str]], + ) -> Tuple[firestore_admin.ListBackupsRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for list_backups + + Override in a subclass to manipulate the request or metadata + before they are sent to the FirestoreAdmin server. + """ + return request, metadata + + def post_list_backups( + self, response: firestore_admin.ListBackupsResponse + ) -> firestore_admin.ListBackupsResponse: + """Post-rpc interceptor for list_backups + + Override in a subclass to manipulate the response + after it is returned by the FirestoreAdmin server but before + it is returned to user code. + """ + return response + + def pre_list_backup_schedules( + self, + request: firestore_admin.ListBackupSchedulesRequest, + metadata: Sequence[Tuple[str, str]], + ) -> Tuple[firestore_admin.ListBackupSchedulesRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for list_backup_schedules + + Override in a subclass to manipulate the request or metadata + before they are sent to the FirestoreAdmin server. + """ + return request, metadata + + def post_list_backup_schedules( + self, response: firestore_admin.ListBackupSchedulesResponse + ) -> firestore_admin.ListBackupSchedulesResponse: + """Post-rpc interceptor for list_backup_schedules + + Override in a subclass to manipulate the response + after it is returned by the FirestoreAdmin server but before + it is returned to user code. + """ + return response + def pre_list_databases( self, request: firestore_admin.ListDatabasesRequest, @@ -449,6 +652,52 @@ def post_list_indexes( """ return response + def pre_restore_database( + self, + request: firestore_admin.RestoreDatabaseRequest, + metadata: Sequence[Tuple[str, str]], + ) -> Tuple[firestore_admin.RestoreDatabaseRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for restore_database + + Override in a subclass to manipulate the request or metadata + before they are sent to the FirestoreAdmin server. + """ + return request, metadata + + def post_restore_database( + self, response: operations_pb2.Operation + ) -> operations_pb2.Operation: + """Post-rpc interceptor for restore_database + + Override in a subclass to manipulate the response + after it is returned by the FirestoreAdmin server but before + it is returned to user code. + """ + return response + + def pre_update_backup_schedule( + self, + request: firestore_admin.UpdateBackupScheduleRequest, + metadata: Sequence[Tuple[str, str]], + ) -> Tuple[firestore_admin.UpdateBackupScheduleRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for update_backup_schedule + + Override in a subclass to manipulate the request or metadata + before they are sent to the FirestoreAdmin server. + """ + return request, metadata + + def post_update_backup_schedule( + self, response: schedule.BackupSchedule + ) -> schedule.BackupSchedule: + """Post-rpc interceptor for update_backup_schedule + + Override in a subclass to manipulate the response + after it is returned by the FirestoreAdmin server but before + it is returned to user code. + """ + return response + def pre_update_database( self, request: firestore_admin.UpdateDatabaseRequest, @@ -764,13 +1013,11 @@ def operations_client(self) -> operations_v1.AbstractOperationsClient: # Return the client from cache. return self._operations_client - class _CreateDatabase(FirestoreAdminRestStub): + class _CreateBackupSchedule(FirestoreAdminRestStub): def __hash__(self): - return hash("CreateDatabase") + return hash("CreateBackupSchedule") - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { - "databaseId": "", - } + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} @classmethod def _get_unset_required_fields(cls, message_dict): @@ -782,18 +1029,18 @@ def _get_unset_required_fields(cls, message_dict): def __call__( self, - request: firestore_admin.CreateDatabaseRequest, + request: firestore_admin.CreateBackupScheduleRequest, *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, metadata: Sequence[Tuple[str, str]] = (), - ) -> operations_pb2.Operation: - r"""Call the create database method over HTTP. + ) -> schedule.BackupSchedule: + r"""Call the create backup schedule method over HTTP. Args: - request (~.firestore_admin.CreateDatabaseRequest): + request (~.firestore_admin.CreateBackupScheduleRequest): The request object. The request for - [FirestoreAdmin.CreateDatabase][google.firestore.admin.v1.FirestoreAdmin.CreateDatabase]. + [FirestoreAdmin.CreateBackupSchedule][google.firestore.admin.v1.FirestoreAdmin.CreateBackupSchedule]. retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. @@ -801,22 +1048,27 @@ def __call__( sent along with the request as metadata. Returns: - ~.operations_pb2.Operation: - This resource represents a - long-running operation that is the - result of a network API call. + ~.schedule.BackupSchedule: + A backup schedule for a Cloud + Firestore Database. + This resource is owned by the database + it is backing up, and is deleted along + with the database. The actual backups + are not though. """ http_options: List[Dict[str, str]] = [ { "method": "post", - "uri": "/v1/{parent=projects/*}/databases", - "body": "database", + "uri": "/v1/{parent=projects/*/databases/*}/backupSchedules", + "body": "backup_schedule", }, ] - request, metadata = self._interceptor.pre_create_database(request, metadata) - pb_request = firestore_admin.CreateDatabaseRequest.pb(request) + request, metadata = self._interceptor.pre_create_backup_schedule( + request, metadata + ) + pb_request = firestore_admin.CreateBackupScheduleRequest.pb(request) transcoded_request = path_template.transcode(http_options, pb_request) # Jsonify the request body @@ -855,16 +1107,20 @@ def __call__( raise core_exceptions.from_http_response(response) # Return the response - resp = operations_pb2.Operation() - json_format.Parse(response.content, resp, ignore_unknown_fields=True) - resp = self._interceptor.post_create_database(resp) + resp = schedule.BackupSchedule() + pb_resp = schedule.BackupSchedule.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_create_backup_schedule(resp) return resp - class _CreateIndex(FirestoreAdminRestStub): + class _CreateDatabase(FirestoreAdminRestStub): def __hash__(self): - return hash("CreateIndex") + return hash("CreateDatabase") - __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + "databaseId": "", + } @classmethod def _get_unset_required_fields(cls, message_dict): @@ -876,18 +1132,18 @@ def _get_unset_required_fields(cls, message_dict): def __call__( self, - request: firestore_admin.CreateIndexRequest, + request: firestore_admin.CreateDatabaseRequest, *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, metadata: Sequence[Tuple[str, str]] = (), ) -> operations_pb2.Operation: - r"""Call the create index method over HTTP. + r"""Call the create database method over HTTP. Args: - request (~.firestore_admin.CreateIndexRequest): + request (~.firestore_admin.CreateDatabaseRequest): The request object. The request for - [FirestoreAdmin.CreateIndex][google.firestore.admin.v1.FirestoreAdmin.CreateIndex]. + [FirestoreAdmin.CreateDatabase][google.firestore.admin.v1.FirestoreAdmin.CreateDatabase]. retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. @@ -905,12 +1161,12 @@ def __call__( http_options: List[Dict[str, str]] = [ { "method": "post", - "uri": "/v1/{parent=projects/*/databases/*/collectionGroups/*}/indexes", - "body": "index", + "uri": "/v1/{parent=projects/*}/databases", + "body": "database", }, ] - request, metadata = self._interceptor.pre_create_index(request, metadata) - pb_request = firestore_admin.CreateIndexRequest.pb(request) + request, metadata = self._interceptor.pre_create_database(request, metadata) + pb_request = firestore_admin.CreateDatabaseRequest.pb(request) transcoded_request = path_template.transcode(http_options, pb_request) # Jsonify the request body @@ -951,12 +1207,12 @@ def __call__( # Return the response resp = operations_pb2.Operation() json_format.Parse(response.content, resp, ignore_unknown_fields=True) - resp = self._interceptor.post_create_index(resp) + resp = self._interceptor.post_create_database(resp) return resp - class _DeleteDatabase(FirestoreAdminRestStub): + class _CreateIndex(FirestoreAdminRestStub): def __hash__(self): - return hash("DeleteDatabase") + return hash("CreateIndex") __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} @@ -970,18 +1226,18 @@ def _get_unset_required_fields(cls, message_dict): def __call__( self, - request: firestore_admin.DeleteDatabaseRequest, + request: firestore_admin.CreateIndexRequest, *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, metadata: Sequence[Tuple[str, str]] = (), ) -> operations_pb2.Operation: - r"""Call the delete database method over HTTP. + r"""Call the create index method over HTTP. Args: - request (~.firestore_admin.DeleteDatabaseRequest): + request (~.firestore_admin.CreateIndexRequest): The request object. The request for - [FirestoreAdmin.DeleteDatabase][google.firestore.admin.v1.FirestoreAdmin.DeleteDatabase]. + [FirestoreAdmin.CreateIndex][google.firestore.admin.v1.FirestoreAdmin.CreateIndex]. retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. @@ -998,14 +1254,20 @@ def __call__( http_options: List[Dict[str, str]] = [ { - "method": "delete", - "uri": "/v1/{name=projects/*/databases/*}", + "method": "post", + "uri": "/v1/{parent=projects/*/databases/*/collectionGroups/*}/indexes", + "body": "index", }, ] - request, metadata = self._interceptor.pre_delete_database(request, metadata) - pb_request = firestore_admin.DeleteDatabaseRequest.pb(request) + request, metadata = self._interceptor.pre_create_index(request, metadata) + pb_request = firestore_admin.CreateIndexRequest.pb(request) transcoded_request = path_template.transcode(http_options, pb_request) + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) uri = transcoded_request["uri"] method = transcoded_request["method"] @@ -1028,6 +1290,7 @@ def __call__( timeout=timeout, headers=headers, params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -1038,12 +1301,12 @@ def __call__( # Return the response resp = operations_pb2.Operation() json_format.Parse(response.content, resp, ignore_unknown_fields=True) - resp = self._interceptor.post_delete_database(resp) + resp = self._interceptor.post_create_index(resp) return resp - class _DeleteIndex(FirestoreAdminRestStub): + class _DeleteBackup(FirestoreAdminRestStub): def __hash__(self): - return hash("DeleteIndex") + return hash("DeleteBackup") __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} @@ -1057,13 +1320,250 @@ def _get_unset_required_fields(cls, message_dict): def __call__( self, - request: firestore_admin.DeleteIndexRequest, + request: firestore_admin.DeleteBackupRequest, *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, metadata: Sequence[Tuple[str, str]] = (), ): - r"""Call the delete index method over HTTP. + r"""Call the delete backup method over HTTP. + + Args: + request (~.firestore_admin.DeleteBackupRequest): + The request object. The request for + [FirestoreAdmin.DeleteBackup][google.firestore.admin.v1.FirestoreAdmin.DeleteBackup]. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + + http_options: List[Dict[str, str]] = [ + { + "method": "delete", + "uri": "/v1/{name=projects/*/locations/*/backups/*}", + }, + ] + request, metadata = self._interceptor.pre_delete_backup(request, metadata) + pb_request = firestore_admin.DeleteBackupRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + uri = transcoded_request["uri"] + method = transcoded_request["method"] + + # Jsonify the query params + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + class _DeleteBackupSchedule(FirestoreAdminRestStub): + def __hash__(self): + return hash("DeleteBackupSchedule") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + def __call__( + self, + request: firestore_admin.DeleteBackupScheduleRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, str]] = (), + ): + r"""Call the delete backup schedule method over HTTP. + + Args: + request (~.firestore_admin.DeleteBackupScheduleRequest): + The request object. The request for + [FirestoreAdmin.DeleteBackupSchedules][]. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + """ + + http_options: List[Dict[str, str]] = [ + { + "method": "delete", + "uri": "/v1/{name=projects/*/databases/*/backupSchedules/*}", + }, + ] + request, metadata = self._interceptor.pre_delete_backup_schedule( + request, metadata + ) + pb_request = firestore_admin.DeleteBackupScheduleRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + uri = transcoded_request["uri"] + method = transcoded_request["method"] + + # Jsonify the query params + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + class _DeleteDatabase(FirestoreAdminRestStub): + def __hash__(self): + return hash("DeleteDatabase") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + def __call__( + self, + request: firestore_admin.DeleteDatabaseRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.Operation: + r"""Call the delete database method over HTTP. + + Args: + request (~.firestore_admin.DeleteDatabaseRequest): + The request object. The request for + [FirestoreAdmin.DeleteDatabase][google.firestore.admin.v1.FirestoreAdmin.DeleteDatabase]. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.operations_pb2.Operation: + This resource represents a + long-running operation that is the + result of a network API call. + + """ + + http_options: List[Dict[str, str]] = [ + { + "method": "delete", + "uri": "/v1/{name=projects/*/databases/*}", + }, + ] + request, metadata = self._interceptor.pre_delete_database(request, metadata) + pb_request = firestore_admin.DeleteDatabaseRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + uri = transcoded_request["uri"] + method = transcoded_request["method"] + + # Jsonify the query params + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = operations_pb2.Operation() + json_format.Parse(response.content, resp, ignore_unknown_fields=True) + resp = self._interceptor.post_delete_database(resp) + return resp + + class _DeleteIndex(FirestoreAdminRestStub): + def __hash__(self): + return hash("DeleteIndex") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + def __call__( + self, + request: firestore_admin.DeleteIndexRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, str]] = (), + ): + r"""Call the delete index method over HTTP. Args: request (~.firestore_admin.DeleteIndexRequest): @@ -1211,9 +1711,9 @@ def __call__( resp = self._interceptor.post_export_documents(resp) return resp - class _GetDatabase(FirestoreAdminRestStub): + class _GetBackup(FirestoreAdminRestStub): def __hash__(self): - return hash("GetDatabase") + return hash("GetBackup") __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} @@ -1227,18 +1727,18 @@ def _get_unset_required_fields(cls, message_dict): def __call__( self, - request: firestore_admin.GetDatabaseRequest, + request: firestore_admin.GetBackupRequest, *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, metadata: Sequence[Tuple[str, str]] = (), - ) -> database.Database: - r"""Call the get database method over HTTP. + ) -> backup.Backup: + r"""Call the get backup method over HTTP. Args: - request (~.firestore_admin.GetDatabaseRequest): + request (~.firestore_admin.GetBackupRequest): The request object. The request for - [FirestoreAdmin.GetDatabase][google.firestore.admin.v1.FirestoreAdmin.GetDatabase]. + [FirestoreAdmin.GetBackup][google.firestore.admin.v1.FirestoreAdmin.GetBackup]. retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. @@ -1246,18 +1746,23 @@ def __call__( sent along with the request as metadata. Returns: - ~.database.Database: - A Cloud Firestore Database. + ~.backup.Backup: + A Backup of a Cloud Firestore + Database. + The backup contains all documents and + index configurations for the given + database at a specific point in time. + """ http_options: List[Dict[str, str]] = [ { "method": "get", - "uri": "/v1/{name=projects/*/databases/*}", + "uri": "/v1/{name=projects/*/locations/*/backups/*}", }, ] - request, metadata = self._interceptor.pre_get_database(request, metadata) - pb_request = firestore_admin.GetDatabaseRequest.pb(request) + request, metadata = self._interceptor.pre_get_backup(request, metadata) + pb_request = firestore_admin.GetBackupRequest.pb(request) transcoded_request = path_template.transcode(http_options, pb_request) uri = transcoded_request["uri"] @@ -1290,16 +1795,560 @@ def __call__( raise core_exceptions.from_http_response(response) # Return the response - resp = database.Database() - pb_resp = database.Database.pb(resp) + resp = backup.Backup() + pb_resp = backup.Backup.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_get_backup(resp) + return resp + + class _GetBackupSchedule(FirestoreAdminRestStub): + def __hash__(self): + return hash("GetBackupSchedule") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + def __call__( + self, + request: firestore_admin.GetBackupScheduleRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> schedule.BackupSchedule: + r"""Call the get backup schedule method over HTTP. + + Args: + request (~.firestore_admin.GetBackupScheduleRequest): + The request object. The request for + [FirestoreAdmin.GetBackupSchedule][google.firestore.admin.v1.FirestoreAdmin.GetBackupSchedule]. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.schedule.BackupSchedule: + A backup schedule for a Cloud + Firestore Database. + This resource is owned by the database + it is backing up, and is deleted along + with the database. The actual backups + are not though. + + """ + + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{name=projects/*/databases/*/backupSchedules/*}", + }, + ] + request, metadata = self._interceptor.pre_get_backup_schedule( + request, metadata + ) + pb_request = firestore_admin.GetBackupScheduleRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + uri = transcoded_request["uri"] + method = transcoded_request["method"] + + # Jsonify the query params + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = schedule.BackupSchedule() + pb_resp = schedule.BackupSchedule.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_get_backup_schedule(resp) + return resp + + class _GetDatabase(FirestoreAdminRestStub): + def __hash__(self): + return hash("GetDatabase") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + def __call__( + self, + request: firestore_admin.GetDatabaseRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> database.Database: + r"""Call the get database method over HTTP. + + Args: + request (~.firestore_admin.GetDatabaseRequest): + The request object. The request for + [FirestoreAdmin.GetDatabase][google.firestore.admin.v1.FirestoreAdmin.GetDatabase]. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.database.Database: + A Cloud Firestore Database. + """ + + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{name=projects/*/databases/*}", + }, + ] + request, metadata = self._interceptor.pre_get_database(request, metadata) + pb_request = firestore_admin.GetDatabaseRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + uri = transcoded_request["uri"] + method = transcoded_request["method"] + + # Jsonify the query params + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = database.Database() + pb_resp = database.Database.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_get_database(resp) + return resp + + class _GetField(FirestoreAdminRestStub): + def __hash__(self): + return hash("GetField") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + def __call__( + self, + request: firestore_admin.GetFieldRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> field.Field: + r"""Call the get field method over HTTP. + + Args: + request (~.firestore_admin.GetFieldRequest): + The request object. The request for + [FirestoreAdmin.GetField][google.firestore.admin.v1.FirestoreAdmin.GetField]. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.field.Field: + Represents a single field in the + database. + Fields are grouped by their "Collection + Group", which represent all collections + in the database with the same id. + + """ + + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{name=projects/*/databases/*/collectionGroups/*/fields/*}", + }, + ] + request, metadata = self._interceptor.pre_get_field(request, metadata) + pb_request = firestore_admin.GetFieldRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + uri = transcoded_request["uri"] + method = transcoded_request["method"] + + # Jsonify the query params + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = field.Field() + pb_resp = field.Field.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_get_field(resp) + return resp + + class _GetIndex(FirestoreAdminRestStub): + def __hash__(self): + return hash("GetIndex") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + def __call__( + self, + request: firestore_admin.GetIndexRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> index.Index: + r"""Call the get index method over HTTP. + + Args: + request (~.firestore_admin.GetIndexRequest): + The request object. The request for + [FirestoreAdmin.GetIndex][google.firestore.admin.v1.FirestoreAdmin.GetIndex]. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.index.Index: + Cloud Firestore indexes enable simple + and complex queries against documents in + a database. + + """ + + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{name=projects/*/databases/*/collectionGroups/*/indexes/*}", + }, + ] + request, metadata = self._interceptor.pre_get_index(request, metadata) + pb_request = firestore_admin.GetIndexRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + uri = transcoded_request["uri"] + method = transcoded_request["method"] + + # Jsonify the query params + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = index.Index() + pb_resp = index.Index.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_get_index(resp) + return resp + + class _ImportDocuments(FirestoreAdminRestStub): + def __hash__(self): + return hash("ImportDocuments") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + def __call__( + self, + request: firestore_admin.ImportDocumentsRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.Operation: + r"""Call the import documents method over HTTP. + + Args: + request (~.firestore_admin.ImportDocumentsRequest): + The request object. The request for + [FirestoreAdmin.ImportDocuments][google.firestore.admin.v1.FirestoreAdmin.ImportDocuments]. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.operations_pb2.Operation: + This resource represents a + long-running operation that is the + result of a network API call. + + """ + + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/v1/{name=projects/*/databases/*}:importDocuments", + "body": "*", + }, + ] + request, metadata = self._interceptor.pre_import_documents( + request, metadata + ) + pb_request = firestore_admin.ImportDocumentsRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) + uri = transcoded_request["uri"] + method = transcoded_request["method"] + + # Jsonify the query params + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = operations_pb2.Operation() + json_format.Parse(response.content, resp, ignore_unknown_fields=True) + resp = self._interceptor.post_import_documents(resp) + return resp + + class _ListBackups(FirestoreAdminRestStub): + def __hash__(self): + return hash("ListBackups") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + def __call__( + self, + request: firestore_admin.ListBackupsRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> firestore_admin.ListBackupsResponse: + r"""Call the list backups method over HTTP. + + Args: + request (~.firestore_admin.ListBackupsRequest): + The request object. The request for + [FirestoreAdmin.ListBackups][google.firestore.admin.v1.FirestoreAdmin.ListBackups]. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.firestore_admin.ListBackupsResponse: + The response for + [FirestoreAdmin.ListBackups][google.firestore.admin.v1.FirestoreAdmin.ListBackups]. + + """ + + http_options: List[Dict[str, str]] = [ + { + "method": "get", + "uri": "/v1/{parent=projects/*/locations/*}/backups", + }, + ] + request, metadata = self._interceptor.pre_list_backups(request, metadata) + pb_request = firestore_admin.ListBackupsRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + uri = transcoded_request["uri"] + method = transcoded_request["method"] + + # Jsonify the query params + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + use_integers_for_enums=True, + ) + ) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = firestore_admin.ListBackupsResponse() + pb_resp = firestore_admin.ListBackupsResponse.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) - resp = self._interceptor.post_get_database(resp) + resp = self._interceptor.post_list_backups(resp) return resp - class _GetField(FirestoreAdminRestStub): + class _ListBackupSchedules(FirestoreAdminRestStub): def __hash__(self): - return hash("GetField") + return hash("ListBackupSchedules") __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} @@ -1313,18 +2362,18 @@ def _get_unset_required_fields(cls, message_dict): def __call__( self, - request: firestore_admin.GetFieldRequest, + request: firestore_admin.ListBackupSchedulesRequest, *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, metadata: Sequence[Tuple[str, str]] = (), - ) -> field.Field: - r"""Call the get field method over HTTP. + ) -> firestore_admin.ListBackupSchedulesResponse: + r"""Call the list backup schedules method over HTTP. Args: - request (~.firestore_admin.GetFieldRequest): + request (~.firestore_admin.ListBackupSchedulesRequest): The request object. The request for - [FirestoreAdmin.GetField][google.firestore.admin.v1.FirestoreAdmin.GetField]. + [FirestoreAdmin.ListBackupSchedules][google.firestore.admin.v1.FirestoreAdmin.ListBackupSchedules]. retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. @@ -1332,23 +2381,22 @@ def __call__( sent along with the request as metadata. Returns: - ~.field.Field: - Represents a single field in the - database. - Fields are grouped by their "Collection - Group", which represent all collections - in the database with the same id. + ~.firestore_admin.ListBackupSchedulesResponse: + The response for + [FirestoreAdmin.ListBackupSchedules][google.firestore.admin.v1.FirestoreAdmin.ListBackupSchedules]. """ http_options: List[Dict[str, str]] = [ { "method": "get", - "uri": "/v1/{name=projects/*/databases/*/collectionGroups/*/fields/*}", + "uri": "/v1/{parent=projects/*/databases/*}/backupSchedules", }, ] - request, metadata = self._interceptor.pre_get_field(request, metadata) - pb_request = firestore_admin.GetFieldRequest.pb(request) + request, metadata = self._interceptor.pre_list_backup_schedules( + request, metadata + ) + pb_request = firestore_admin.ListBackupSchedulesRequest.pb(request) transcoded_request = path_template.transcode(http_options, pb_request) uri = transcoded_request["uri"] @@ -1381,16 +2429,16 @@ def __call__( raise core_exceptions.from_http_response(response) # Return the response - resp = field.Field() - pb_resp = field.Field.pb(resp) + resp = firestore_admin.ListBackupSchedulesResponse() + pb_resp = firestore_admin.ListBackupSchedulesResponse.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) - resp = self._interceptor.post_get_field(resp) + resp = self._interceptor.post_list_backup_schedules(resp) return resp - class _GetIndex(FirestoreAdminRestStub): + class _ListDatabases(FirestoreAdminRestStub): def __hash__(self): - return hash("GetIndex") + return hash("ListDatabases") __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} @@ -1404,18 +2452,19 @@ def _get_unset_required_fields(cls, message_dict): def __call__( self, - request: firestore_admin.GetIndexRequest, + request: firestore_admin.ListDatabasesRequest, *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, metadata: Sequence[Tuple[str, str]] = (), - ) -> index.Index: - r"""Call the get index method over HTTP. + ) -> firestore_admin.ListDatabasesResponse: + r"""Call the list databases method over HTTP. Args: - request (~.firestore_admin.GetIndexRequest): - The request object. The request for - [FirestoreAdmin.GetIndex][google.firestore.admin.v1.FirestoreAdmin.GetIndex]. + request (~.firestore_admin.ListDatabasesRequest): + The request object. A request to list the Firestore + Databases in all locations for a + project. retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. @@ -1423,21 +2472,18 @@ def __call__( sent along with the request as metadata. Returns: - ~.index.Index: - Cloud Firestore indexes enable simple - and complex queries against documents in - a database. - + ~.firestore_admin.ListDatabasesResponse: + The list of databases for a project. """ http_options: List[Dict[str, str]] = [ { "method": "get", - "uri": "/v1/{name=projects/*/databases/*/collectionGroups/*/indexes/*}", + "uri": "/v1/{parent=projects/*}/databases", }, ] - request, metadata = self._interceptor.pre_get_index(request, metadata) - pb_request = firestore_admin.GetIndexRequest.pb(request) + request, metadata = self._interceptor.pre_list_databases(request, metadata) + pb_request = firestore_admin.ListDatabasesRequest.pb(request) transcoded_request = path_template.transcode(http_options, pb_request) uri = transcoded_request["uri"] @@ -1470,16 +2516,16 @@ def __call__( raise core_exceptions.from_http_response(response) # Return the response - resp = index.Index() - pb_resp = index.Index.pb(resp) + resp = firestore_admin.ListDatabasesResponse() + pb_resp = firestore_admin.ListDatabasesResponse.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) - resp = self._interceptor.post_get_index(resp) + resp = self._interceptor.post_list_databases(resp) return resp - class _ImportDocuments(FirestoreAdminRestStub): + class _ListFields(FirestoreAdminRestStub): def __hash__(self): - return hash("ImportDocuments") + return hash("ListFields") __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} @@ -1493,18 +2539,18 @@ def _get_unset_required_fields(cls, message_dict): def __call__( self, - request: firestore_admin.ImportDocumentsRequest, + request: firestore_admin.ListFieldsRequest, *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, metadata: Sequence[Tuple[str, str]] = (), - ) -> operations_pb2.Operation: - r"""Call the import documents method over HTTP. + ) -> firestore_admin.ListFieldsResponse: + r"""Call the list fields method over HTTP. Args: - request (~.firestore_admin.ImportDocumentsRequest): + request (~.firestore_admin.ListFieldsRequest): The request object. The request for - [FirestoreAdmin.ImportDocuments][google.firestore.admin.v1.FirestoreAdmin.ImportDocuments]. + [FirestoreAdmin.ListFields][google.firestore.admin.v1.FirestoreAdmin.ListFields]. retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. @@ -1512,31 +2558,22 @@ def __call__( sent along with the request as metadata. Returns: - ~.operations_pb2.Operation: - This resource represents a - long-running operation that is the - result of a network API call. + ~.firestore_admin.ListFieldsResponse: + The response for + [FirestoreAdmin.ListFields][google.firestore.admin.v1.FirestoreAdmin.ListFields]. """ http_options: List[Dict[str, str]] = [ { - "method": "post", - "uri": "/v1/{name=projects/*/databases/*}:importDocuments", - "body": "*", + "method": "get", + "uri": "/v1/{parent=projects/*/databases/*/collectionGroups/*}/fields", }, ] - request, metadata = self._interceptor.pre_import_documents( - request, metadata - ) - pb_request = firestore_admin.ImportDocumentsRequest.pb(request) + request, metadata = self._interceptor.pre_list_fields(request, metadata) + pb_request = firestore_admin.ListFieldsRequest.pb(request) transcoded_request = path_template.transcode(http_options, pb_request) - # Jsonify the request body - - body = json_format.MessageToJson( - transcoded_request["body"], use_integers_for_enums=True - ) uri = transcoded_request["uri"] method = transcoded_request["method"] @@ -1559,7 +2596,6 @@ def __call__( timeout=timeout, headers=headers, params=rest_helpers.flatten_query_params(query_params, strict=True), - data=body, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -1568,14 +2604,16 @@ def __call__( raise core_exceptions.from_http_response(response) # Return the response - resp = operations_pb2.Operation() - json_format.Parse(response.content, resp, ignore_unknown_fields=True) - resp = self._interceptor.post_import_documents(resp) + resp = firestore_admin.ListFieldsResponse() + pb_resp = firestore_admin.ListFieldsResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_list_fields(resp) return resp - class _ListDatabases(FirestoreAdminRestStub): + class _ListIndexes(FirestoreAdminRestStub): def __hash__(self): - return hash("ListDatabases") + return hash("ListIndexes") __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} @@ -1589,19 +2627,18 @@ def _get_unset_required_fields(cls, message_dict): def __call__( self, - request: firestore_admin.ListDatabasesRequest, + request: firestore_admin.ListIndexesRequest, *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, metadata: Sequence[Tuple[str, str]] = (), - ) -> firestore_admin.ListDatabasesResponse: - r"""Call the list databases method over HTTP. + ) -> firestore_admin.ListIndexesResponse: + r"""Call the list indexes method over HTTP. Args: - request (~.firestore_admin.ListDatabasesRequest): - The request object. A request to list the Firestore - Databases in all locations for a - project. + request (~.firestore_admin.ListIndexesRequest): + The request object. The request for + [FirestoreAdmin.ListIndexes][google.firestore.admin.v1.FirestoreAdmin.ListIndexes]. retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. @@ -1609,18 +2646,20 @@ def __call__( sent along with the request as metadata. Returns: - ~.firestore_admin.ListDatabasesResponse: - The list of databases for a project. + ~.firestore_admin.ListIndexesResponse: + The response for + [FirestoreAdmin.ListIndexes][google.firestore.admin.v1.FirestoreAdmin.ListIndexes]. + """ http_options: List[Dict[str, str]] = [ { "method": "get", - "uri": "/v1/{parent=projects/*}/databases", + "uri": "/v1/{parent=projects/*/databases/*/collectionGroups/*}/indexes", }, ] - request, metadata = self._interceptor.pre_list_databases(request, metadata) - pb_request = firestore_admin.ListDatabasesRequest.pb(request) + request, metadata = self._interceptor.pre_list_indexes(request, metadata) + pb_request = firestore_admin.ListIndexesRequest.pb(request) transcoded_request = path_template.transcode(http_options, pb_request) uri = transcoded_request["uri"] @@ -1653,16 +2692,16 @@ def __call__( raise core_exceptions.from_http_response(response) # Return the response - resp = firestore_admin.ListDatabasesResponse() - pb_resp = firestore_admin.ListDatabasesResponse.pb(resp) + resp = firestore_admin.ListIndexesResponse() + pb_resp = firestore_admin.ListIndexesResponse.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) - resp = self._interceptor.post_list_databases(resp) + resp = self._interceptor.post_list_indexes(resp) return resp - class _ListFields(FirestoreAdminRestStub): + class _RestoreDatabase(FirestoreAdminRestStub): def __hash__(self): - return hash("ListFields") + return hash("RestoreDatabase") __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} @@ -1676,18 +2715,18 @@ def _get_unset_required_fields(cls, message_dict): def __call__( self, - request: firestore_admin.ListFieldsRequest, + request: firestore_admin.RestoreDatabaseRequest, *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, metadata: Sequence[Tuple[str, str]] = (), - ) -> firestore_admin.ListFieldsResponse: - r"""Call the list fields method over HTTP. + ) -> operations_pb2.Operation: + r"""Call the restore database method over HTTP. Args: - request (~.firestore_admin.ListFieldsRequest): - The request object. The request for - [FirestoreAdmin.ListFields][google.firestore.admin.v1.FirestoreAdmin.ListFields]. + request (~.firestore_admin.RestoreDatabaseRequest): + The request object. The request message for + [FirestoreAdmin.RestoreDatabase][google.firestore.admin.v1.RestoreDatabase]. retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. @@ -1695,22 +2734,31 @@ def __call__( sent along with the request as metadata. Returns: - ~.firestore_admin.ListFieldsResponse: - The response for - [FirestoreAdmin.ListFields][google.firestore.admin.v1.FirestoreAdmin.ListFields]. + ~.operations_pb2.Operation: + This resource represents a + long-running operation that is the + result of a network API call. """ http_options: List[Dict[str, str]] = [ { - "method": "get", - "uri": "/v1/{parent=projects/*/databases/*/collectionGroups/*}/fields", + "method": "post", + "uri": "/v1/{parent=projects/*}/databases:restore", + "body": "*", }, ] - request, metadata = self._interceptor.pre_list_fields(request, metadata) - pb_request = firestore_admin.ListFieldsRequest.pb(request) + request, metadata = self._interceptor.pre_restore_database( + request, metadata + ) + pb_request = firestore_admin.RestoreDatabaseRequest.pb(request) transcoded_request = path_template.transcode(http_options, pb_request) + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) uri = transcoded_request["uri"] method = transcoded_request["method"] @@ -1733,6 +2781,7 @@ def __call__( timeout=timeout, headers=headers, params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -1741,16 +2790,14 @@ def __call__( raise core_exceptions.from_http_response(response) # Return the response - resp = firestore_admin.ListFieldsResponse() - pb_resp = firestore_admin.ListFieldsResponse.pb(resp) - - json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) - resp = self._interceptor.post_list_fields(resp) + resp = operations_pb2.Operation() + json_format.Parse(response.content, resp, ignore_unknown_fields=True) + resp = self._interceptor.post_restore_database(resp) return resp - class _ListIndexes(FirestoreAdminRestStub): + class _UpdateBackupSchedule(FirestoreAdminRestStub): def __hash__(self): - return hash("ListIndexes") + return hash("UpdateBackupSchedule") __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} @@ -1764,18 +2811,18 @@ def _get_unset_required_fields(cls, message_dict): def __call__( self, - request: firestore_admin.ListIndexesRequest, + request: firestore_admin.UpdateBackupScheduleRequest, *, retry: OptionalRetry = gapic_v1.method.DEFAULT, timeout: Optional[float] = None, metadata: Sequence[Tuple[str, str]] = (), - ) -> firestore_admin.ListIndexesResponse: - r"""Call the list indexes method over HTTP. + ) -> schedule.BackupSchedule: + r"""Call the update backup schedule method over HTTP. Args: - request (~.firestore_admin.ListIndexesRequest): + request (~.firestore_admin.UpdateBackupScheduleRequest): The request object. The request for - [FirestoreAdmin.ListIndexes][google.firestore.admin.v1.FirestoreAdmin.ListIndexes]. + [FirestoreAdmin.UpdateBackupSchedule][google.firestore.admin.v1.FirestoreAdmin.UpdateBackupSchedule]. retry (google.api_core.retry.Retry): Designation of what errors, if any, should be retried. timeout (float): The timeout for this request. @@ -1783,22 +2830,34 @@ def __call__( sent along with the request as metadata. Returns: - ~.firestore_admin.ListIndexesResponse: - The response for - [FirestoreAdmin.ListIndexes][google.firestore.admin.v1.FirestoreAdmin.ListIndexes]. + ~.schedule.BackupSchedule: + A backup schedule for a Cloud + Firestore Database. + This resource is owned by the database + it is backing up, and is deleted along + with the database. The actual backups + are not though. """ http_options: List[Dict[str, str]] = [ { - "method": "get", - "uri": "/v1/{parent=projects/*/databases/*/collectionGroups/*}/indexes", + "method": "patch", + "uri": "/v1/{backup_schedule.name=projects/*/databases/*/backupSchedules/*}", + "body": "backup_schedule", }, ] - request, metadata = self._interceptor.pre_list_indexes(request, metadata) - pb_request = firestore_admin.ListIndexesRequest.pb(request) + request, metadata = self._interceptor.pre_update_backup_schedule( + request, metadata + ) + pb_request = firestore_admin.UpdateBackupScheduleRequest.pb(request) transcoded_request = path_template.transcode(http_options, pb_request) + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], use_integers_for_enums=True + ) uri = transcoded_request["uri"] method = transcoded_request["method"] @@ -1821,6 +2880,7 @@ def __call__( timeout=timeout, headers=headers, params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, ) # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception @@ -1829,11 +2889,11 @@ def __call__( raise core_exceptions.from_http_response(response) # Return the response - resp = firestore_admin.ListIndexesResponse() - pb_resp = firestore_admin.ListIndexesResponse.pb(resp) + resp = schedule.BackupSchedule() + pb_resp = schedule.BackupSchedule.pb(resp) json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) - resp = self._interceptor.post_list_indexes(resp) + resp = self._interceptor.post_update_backup_schedule(resp) return resp class _UpdateDatabase(FirestoreAdminRestStub): @@ -2024,6 +3084,16 @@ def __call__( resp = self._interceptor.post_update_field(resp) return resp + @property + def create_backup_schedule( + self, + ) -> Callable[ + [firestore_admin.CreateBackupScheduleRequest], schedule.BackupSchedule + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._CreateBackupSchedule(self._session, self._host, self._interceptor) # type: ignore + @property def create_database( self, @@ -2040,6 +3110,22 @@ def create_index( # In C++ this would require a dynamic_cast return self._CreateIndex(self._session, self._host, self._interceptor) # type: ignore + @property + def delete_backup( + self, + ) -> Callable[[firestore_admin.DeleteBackupRequest], empty_pb2.Empty]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._DeleteBackup(self._session, self._host, self._interceptor) # type: ignore + + @property + def delete_backup_schedule( + self, + ) -> Callable[[firestore_admin.DeleteBackupScheduleRequest], empty_pb2.Empty]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._DeleteBackupSchedule(self._session, self._host, self._interceptor) # type: ignore + @property def delete_database( self, @@ -2064,6 +3150,20 @@ def export_documents( # In C++ this would require a dynamic_cast return self._ExportDocuments(self._session, self._host, self._interceptor) # type: ignore + @property + def get_backup(self) -> Callable[[firestore_admin.GetBackupRequest], backup.Backup]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._GetBackup(self._session, self._host, self._interceptor) # type: ignore + + @property + def get_backup_schedule( + self, + ) -> Callable[[firestore_admin.GetBackupScheduleRequest], schedule.BackupSchedule]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._GetBackupSchedule(self._session, self._host, self._interceptor) # type: ignore + @property def get_database( self, @@ -2092,6 +3192,27 @@ def import_documents( # In C++ this would require a dynamic_cast return self._ImportDocuments(self._session, self._host, self._interceptor) # type: ignore + @property + def list_backups( + self, + ) -> Callable[ + [firestore_admin.ListBackupsRequest], firestore_admin.ListBackupsResponse + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._ListBackups(self._session, self._host, self._interceptor) # type: ignore + + @property + def list_backup_schedules( + self, + ) -> Callable[ + [firestore_admin.ListBackupSchedulesRequest], + firestore_admin.ListBackupSchedulesResponse, + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._ListBackupSchedules(self._session, self._host, self._interceptor) # type: ignore + @property def list_databases( self, @@ -2122,6 +3243,24 @@ def list_indexes( # In C++ this would require a dynamic_cast return self._ListIndexes(self._session, self._host, self._interceptor) # type: ignore + @property + def restore_database( + self, + ) -> Callable[[firestore_admin.RestoreDatabaseRequest], operations_pb2.Operation]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._RestoreDatabase(self._session, self._host, self._interceptor) # type: ignore + + @property + def update_backup_schedule( + self, + ) -> Callable[ + [firestore_admin.UpdateBackupScheduleRequest], schedule.BackupSchedule + ]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._UpdateBackupSchedule(self._session, self._host, self._interceptor) # type: ignore + @property def update_database( self, diff --git a/google/cloud/firestore_admin_v1/types/__init__.py b/google/cloud/firestore_admin_v1/types/__init__.py index 97ce51f09..0405a9481 100644 --- a/google/cloud/firestore_admin_v1/types/__init__.py +++ b/google/cloud/firestore_admin_v1/types/__init__.py @@ -13,6 +13,9 @@ # See the License for the specific language governing permissions and # limitations under the License. # +from .backup import ( + Backup, +) from .database import ( Database, ) @@ -20,23 +23,34 @@ Field, ) from .firestore_admin import ( + CreateBackupScheduleRequest, CreateDatabaseMetadata, CreateDatabaseRequest, CreateIndexRequest, + DeleteBackupRequest, + DeleteBackupScheduleRequest, DeleteDatabaseMetadata, DeleteDatabaseRequest, DeleteIndexRequest, ExportDocumentsRequest, + GetBackupRequest, + GetBackupScheduleRequest, GetDatabaseRequest, GetFieldRequest, GetIndexRequest, ImportDocumentsRequest, + ListBackupSchedulesRequest, + ListBackupSchedulesResponse, + ListBackupsRequest, + ListBackupsResponse, ListDatabasesRequest, ListDatabasesResponse, ListFieldsRequest, ListFieldsResponse, ListIndexesRequest, ListIndexesResponse, + RestoreDatabaseRequest, + UpdateBackupScheduleRequest, UpdateDatabaseMetadata, UpdateDatabaseRequest, UpdateFieldRequest, @@ -54,29 +68,47 @@ ImportDocumentsMetadata, IndexOperationMetadata, Progress, + RestoreDatabaseMetadata, OperationState, ) +from .schedule import ( + BackupSchedule, + DailyRecurrence, + WeeklyRecurrence, +) __all__ = ( + "Backup", "Database", "Field", + "CreateBackupScheduleRequest", "CreateDatabaseMetadata", "CreateDatabaseRequest", "CreateIndexRequest", + "DeleteBackupRequest", + "DeleteBackupScheduleRequest", "DeleteDatabaseMetadata", "DeleteDatabaseRequest", "DeleteIndexRequest", "ExportDocumentsRequest", + "GetBackupRequest", + "GetBackupScheduleRequest", "GetDatabaseRequest", "GetFieldRequest", "GetIndexRequest", "ImportDocumentsRequest", + "ListBackupSchedulesRequest", + "ListBackupSchedulesResponse", + "ListBackupsRequest", + "ListBackupsResponse", "ListDatabasesRequest", "ListDatabasesResponse", "ListFieldsRequest", "ListFieldsResponse", "ListIndexesRequest", "ListIndexesResponse", + "RestoreDatabaseRequest", + "UpdateBackupScheduleRequest", "UpdateDatabaseMetadata", "UpdateDatabaseRequest", "UpdateFieldRequest", @@ -88,5 +120,9 @@ "ImportDocumentsMetadata", "IndexOperationMetadata", "Progress", + "RestoreDatabaseMetadata", "OperationState", + "BackupSchedule", + "DailyRecurrence", + "WeeklyRecurrence", ) diff --git a/google/cloud/firestore_admin_v1/types/backup.py b/google/cloud/firestore_admin_v1/types/backup.py new file mode 100644 index 000000000..f60a92a81 --- /dev/null +++ b/google/cloud/firestore_admin_v1/types/backup.py @@ -0,0 +1,153 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import annotations + +from typing import MutableMapping, MutableSequence + +import proto # type: ignore + +from google.protobuf import timestamp_pb2 # type: ignore + + +__protobuf__ = proto.module( + package="google.firestore.admin.v1", + manifest={ + "Backup", + }, +) + + +class Backup(proto.Message): + r"""A Backup of a Cloud Firestore Database. + + The backup contains all documents and index configurations for + the given database at a specific point in time. + + Attributes: + name (str): + Output only. The unique resource name of the Backup. + + Format is + ``projects/{project}/locations/{location}/backups/{backup}``. + database (str): + Output only. Name of the Firestore database that the backup + is from. + + Format is ``projects/{project}/databases/{database}``. + database_uid (str): + Output only. The system-generated UUID4 for + the Firestore database that the backup is from. + snapshot_time (google.protobuf.timestamp_pb2.Timestamp): + Output only. The backup contains an + externally consistent copy of the database at + this time. + expire_time (google.protobuf.timestamp_pb2.Timestamp): + Output only. The timestamp at which this + backup expires. + stats (google.cloud.firestore_admin_v1.types.Backup.Stats): + Output only. Statistics about the backup. + + This data only becomes available after the + backup is fully materialized to secondary + storage. This field will be empty till then. + state (google.cloud.firestore_admin_v1.types.Backup.State): + Output only. The current state of the backup. + """ + + class State(proto.Enum): + r"""Indicate the current state of the backup. + + Values: + STATE_UNSPECIFIED (0): + The state is unspecified. + CREATING (1): + The pending backup is still being created. + Operations on the backup will be rejected in + this state. + READY (2): + The backup is complete and ready to use. + NOT_AVAILABLE (3): + The backup is not available at this moment. + """ + STATE_UNSPECIFIED = 0 + CREATING = 1 + READY = 2 + NOT_AVAILABLE = 3 + + class Stats(proto.Message): + r"""Backup specific statistics. + + Attributes: + size_bytes (int): + Output only. Summation of the size of all + documents and index entries in the backup, + measured in bytes. + document_count (int): + Output only. The total number of documents + contained in the backup. + index_count (int): + Output only. The total number of index + entries contained in the backup. + """ + + size_bytes: int = proto.Field( + proto.INT64, + number=1, + ) + document_count: int = proto.Field( + proto.INT64, + number=2, + ) + index_count: int = proto.Field( + proto.INT64, + number=3, + ) + + name: str = proto.Field( + proto.STRING, + number=1, + ) + database: str = proto.Field( + proto.STRING, + number=2, + ) + database_uid: str = proto.Field( + proto.STRING, + number=7, + ) + snapshot_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=3, + message=timestamp_pb2.Timestamp, + ) + expire_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=4, + message=timestamp_pb2.Timestamp, + ) + stats: Stats = proto.Field( + proto.MESSAGE, + number=6, + message=Stats, + ) + state: State = proto.Field( + proto.ENUM, + number=8, + enum=State, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/cloud/firestore_admin_v1/types/firestore_admin.py b/google/cloud/firestore_admin_v1/types/firestore_admin.py index a5d3fa7d8..55c8d8ae1 100644 --- a/google/cloud/firestore_admin_v1/types/firestore_admin.py +++ b/google/cloud/firestore_admin_v1/types/firestore_admin.py @@ -19,9 +19,11 @@ import proto # type: ignore +from google.cloud.firestore_admin_v1.types import backup as gfa_backup from google.cloud.firestore_admin_v1.types import database as gfa_database from google.cloud.firestore_admin_v1.types import field as gfa_field from google.cloud.firestore_admin_v1.types import index as gfa_index +from google.cloud.firestore_admin_v1.types import schedule from google.protobuf import field_mask_pb2 # type: ignore from google.protobuf import timestamp_pb2 # type: ignore @@ -38,6 +40,12 @@ "UpdateDatabaseMetadata", "DeleteDatabaseRequest", "DeleteDatabaseMetadata", + "CreateBackupScheduleRequest", + "GetBackupScheduleRequest", + "UpdateBackupScheduleRequest", + "ListBackupSchedulesRequest", + "ListBackupSchedulesResponse", + "DeleteBackupScheduleRequest", "CreateIndexRequest", "ListIndexesRequest", "ListIndexesResponse", @@ -49,6 +57,11 @@ "ListFieldsResponse", "ExportDocumentsRequest", "ImportDocumentsRequest", + "GetBackupRequest", + "ListBackupsRequest", + "ListBackupsResponse", + "DeleteBackupRequest", + "RestoreDatabaseRequest", }, ) @@ -213,6 +226,121 @@ class DeleteDatabaseMetadata(proto.Message): r"""Metadata related to the delete database operation.""" +class CreateBackupScheduleRequest(proto.Message): + r"""The request for + [FirestoreAdmin.CreateBackupSchedule][google.firestore.admin.v1.FirestoreAdmin.CreateBackupSchedule]. + + Attributes: + parent (str): + Required. The parent database. + + Format ``projects/{project}/databases/{database}`` + backup_schedule (google.cloud.firestore_admin_v1.types.BackupSchedule): + Required. The backup schedule to create. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + backup_schedule: schedule.BackupSchedule = proto.Field( + proto.MESSAGE, + number=2, + message=schedule.BackupSchedule, + ) + + +class GetBackupScheduleRequest(proto.Message): + r"""The request for + [FirestoreAdmin.GetBackupSchedule][google.firestore.admin.v1.FirestoreAdmin.GetBackupSchedule]. + + Attributes: + name (str): + Required. The name of the backup schedule. + + Format + ``projects/{project}/databases/{database}/backupSchedules/{backup_schedule}`` + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class UpdateBackupScheduleRequest(proto.Message): + r"""The request for + [FirestoreAdmin.UpdateBackupSchedule][google.firestore.admin.v1.FirestoreAdmin.UpdateBackupSchedule]. + + Attributes: + backup_schedule (google.cloud.firestore_admin_v1.types.BackupSchedule): + Required. The backup schedule to update. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + The list of fields to be updated. + """ + + backup_schedule: schedule.BackupSchedule = proto.Field( + proto.MESSAGE, + number=1, + message=schedule.BackupSchedule, + ) + update_mask: field_mask_pb2.FieldMask = proto.Field( + proto.MESSAGE, + number=2, + message=field_mask_pb2.FieldMask, + ) + + +class ListBackupSchedulesRequest(proto.Message): + r"""The request for + [FirestoreAdmin.ListBackupSchedules][google.firestore.admin.v1.FirestoreAdmin.ListBackupSchedules]. + + Attributes: + parent (str): + Required. The parent database. + + Format is ``projects/{project}/databases/{database}``. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + + +class ListBackupSchedulesResponse(proto.Message): + r"""The response for + [FirestoreAdmin.ListBackupSchedules][google.firestore.admin.v1.FirestoreAdmin.ListBackupSchedules]. + + Attributes: + backup_schedules (MutableSequence[google.cloud.firestore_admin_v1.types.BackupSchedule]): + List of all backup schedules. + """ + + backup_schedules: MutableSequence[schedule.BackupSchedule] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=schedule.BackupSchedule, + ) + + +class DeleteBackupScheduleRequest(proto.Message): + r"""The request for [FirestoreAdmin.DeleteBackupSchedules][]. + + Attributes: + name (str): + Required. The name of backup schedule. + + Format + ``projects/{project}/databases/{database}/backupSchedules/{backup_schedule}`` + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + class CreateIndexRequest(proto.Message): r"""The request for [FirestoreAdmin.CreateIndex][google.firestore.admin.v1.FirestoreAdmin.CreateIndex]. @@ -554,4 +682,131 @@ class ImportDocumentsRequest(proto.Message): ) +class GetBackupRequest(proto.Message): + r"""The request for + [FirestoreAdmin.GetBackup][google.firestore.admin.v1.FirestoreAdmin.GetBackup]. + + Attributes: + name (str): + Required. Name of the backup to fetch. + + Format is + ``projects/{project}/locations/{location}/backups/{backup}``. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class ListBackupsRequest(proto.Message): + r"""The request for + [FirestoreAdmin.ListBackups][google.firestore.admin.v1.FirestoreAdmin.ListBackups]. + + Attributes: + parent (str): + Required. The location to list backups from. + + Format is ``projects/{project}/locations/{location}``. Use + ``{location} = '-'`` to list backups from all locations for + the given project. This allows listing backups from a single + location or from all locations. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + + +class ListBackupsResponse(proto.Message): + r"""The response for + [FirestoreAdmin.ListBackups][google.firestore.admin.v1.FirestoreAdmin.ListBackups]. + + Attributes: + backups (MutableSequence[google.cloud.firestore_admin_v1.types.Backup]): + List of all backups for the project. + unreachable (MutableSequence[str]): + List of locations that existing backups were + not able to be fetched from. + Instead of failing the entire requests when a + single location is unreachable, this response + returns a partial result set and list of + locations unable to be reached here. The request + can be retried against a single location to get + a concrete error. + """ + + backups: MutableSequence[gfa_backup.Backup] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=gfa_backup.Backup, + ) + unreachable: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=3, + ) + + +class DeleteBackupRequest(proto.Message): + r"""The request for + [FirestoreAdmin.DeleteBackup][google.firestore.admin.v1.FirestoreAdmin.DeleteBackup]. + + Attributes: + name (str): + Required. Name of the backup to delete. + + format is + ``projects/{project}/locations/{location}/backups/{backup}``. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class RestoreDatabaseRequest(proto.Message): + r"""The request message for + [FirestoreAdmin.RestoreDatabase][google.firestore.admin.v1.RestoreDatabase]. + + Attributes: + parent (str): + Required. The project to restore the database in. Format is + ``projects/{project_id}``. + database_id (str): + Required. The ID to use for the database, which will become + the final component of the database's resource name. This + database id must not be associated with an existing + database. + + This value should be 4-63 characters. Valid characters are + /[a-z][0-9]-/ with first character a letter and the last a + letter or a number. Must not be UUID-like + /[0-9a-f]{8}(-[0-9a-f]{4}){3}-[0-9a-f]{12}/. + + "(default)" database id is also valid. + backup (str): + Required. Backup to restore from. Must be from the same + project as the parent. + + Format is: + ``projects/{project_id}/locations/{location}/backups/{backup}`` + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + database_id: str = proto.Field( + proto.STRING, + number=2, + ) + backup: str = proto.Field( + proto.STRING, + number=3, + ) + + __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/cloud/firestore_admin_v1/types/operation.py b/google/cloud/firestore_admin_v1/types/operation.py index 7c6cbc2ec..407e77854 100644 --- a/google/cloud/firestore_admin_v1/types/operation.py +++ b/google/cloud/firestore_admin_v1/types/operation.py @@ -32,6 +32,7 @@ "ExportDocumentsMetadata", "ImportDocumentsMetadata", "ExportDocumentsResponse", + "RestoreDatabaseMetadata", "Progress", }, ) @@ -430,6 +431,59 @@ class ExportDocumentsResponse(proto.Message): ) +class RestoreDatabaseMetadata(proto.Message): + r"""Metadata for the [long-running + operation][google.longrunning.Operation] from the + [RestoreDatabase][google.firestore.admin.v1.RestoreDatabase] + request. + + Attributes: + start_time (google.protobuf.timestamp_pb2.Timestamp): + The time the restore was started. + end_time (google.protobuf.timestamp_pb2.Timestamp): + The time the restore finished, unset for + ongoing restores. + operation_state (google.cloud.firestore_admin_v1.types.OperationState): + The operation state of the restore. + database (str): + The name of the database being restored to. + backup (str): + The name of the backup restoring from. + progress_percentage (google.cloud.firestore_admin_v1.types.Progress): + How far along the restore is as an estimated + percentage of remaining time. + """ + + start_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=1, + message=timestamp_pb2.Timestamp, + ) + end_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=2, + message=timestamp_pb2.Timestamp, + ) + operation_state: "OperationState" = proto.Field( + proto.ENUM, + number=3, + enum="OperationState", + ) + database: str = proto.Field( + proto.STRING, + number=4, + ) + backup: str = proto.Field( + proto.STRING, + number=5, + ) + progress_percentage: "Progress" = proto.Field( + proto.MESSAGE, + number=8, + message="Progress", + ) + + class Progress(proto.Message): r"""Describes the progress of the operation. Unit of work is generic and must be interpreted based on where diff --git a/google/cloud/firestore_admin_v1/types/schedule.py b/google/cloud/firestore_admin_v1/types/schedule.py new file mode 100644 index 000000000..00b2ec09e --- /dev/null +++ b/google/cloud/firestore_admin_v1/types/schedule.py @@ -0,0 +1,146 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import annotations + +from typing import MutableMapping, MutableSequence + +import proto # type: ignore + +from google.protobuf import duration_pb2 # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore +from google.type import dayofweek_pb2 # type: ignore + + +__protobuf__ = proto.module( + package="google.firestore.admin.v1", + manifest={ + "BackupSchedule", + "DailyRecurrence", + "WeeklyRecurrence", + }, +) + + +class BackupSchedule(proto.Message): + r"""A backup schedule for a Cloud Firestore Database. + + This resource is owned by the database it is backing up, and is + deleted along with the database. The actual backups are not + though. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + name (str): + Output only. The unique backup schedule identifier across + all locations and databases for the given project. + + This will be auto-assigned. + + Format is + ``projects/{project}/databases/{database}/backupSchedules/{backup_schedule}`` + create_time (google.protobuf.timestamp_pb2.Timestamp): + Output only. The timestamp at which this + backup schedule was created and effective since. + + No backups will be created for this schedule + before this time. + update_time (google.protobuf.timestamp_pb2.Timestamp): + Output only. The timestamp at which this backup schedule was + most recently updated. When a backup schedule is first + created, this is the same as create_time. + retention (google.protobuf.duration_pb2.Duration): + At what relative time in the future, compared + to its creation time, the backup should be + deleted, e.g. keep backups for 7 days. + daily_recurrence (google.cloud.firestore_admin_v1.types.DailyRecurrence): + For a schedule that runs daily at a specified + time. + + This field is a member of `oneof`_ ``recurrence``. + weekly_recurrence (google.cloud.firestore_admin_v1.types.WeeklyRecurrence): + For a schedule that runs weekly on a specific + day and time. + + This field is a member of `oneof`_ ``recurrence``. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + create_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=3, + message=timestamp_pb2.Timestamp, + ) + update_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=10, + message=timestamp_pb2.Timestamp, + ) + retention: duration_pb2.Duration = proto.Field( + proto.MESSAGE, + number=6, + message=duration_pb2.Duration, + ) + daily_recurrence: "DailyRecurrence" = proto.Field( + proto.MESSAGE, + number=7, + oneof="recurrence", + message="DailyRecurrence", + ) + weekly_recurrence: "WeeklyRecurrence" = proto.Field( + proto.MESSAGE, + number=8, + oneof="recurrence", + message="WeeklyRecurrence", + ) + + +class DailyRecurrence(proto.Message): + r"""Represent a recurring schedule that runs at a specific time + every day. + The time zone is UTC. + + """ + + +class WeeklyRecurrence(proto.Message): + r"""Represents a recurring schedule that runs on a specified day + of the week. + The time zone is UTC. + + Attributes: + day (google.type.dayofweek_pb2.DayOfWeek): + The day of week to run. + + DAY_OF_WEEK_UNSPECIFIED is not allowed. + """ + + day: dayofweek_pb2.DayOfWeek = proto.Field( + proto.ENUM, + number=2, + enum=dayofweek_pb2.DayOfWeek, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/google/cloud/firestore_v1/services/firestore/async_client.py b/google/cloud/firestore_v1/services/firestore/async_client.py index 85dc8dae6..ecf9baea4 100644 --- a/google/cloud/firestore_v1/services/firestore/async_client.py +++ b/google/cloud/firestore_v1/services/firestore/async_client.py @@ -52,6 +52,7 @@ from google.cloud.firestore_v1.types import document as gf_document from google.cloud.firestore_v1.types import firestore from google.cloud.firestore_v1.types import query +from google.cloud.firestore_v1.types import query_profile from google.cloud.firestore_v1.types import write as gf_write from google.cloud.location import locations_pb2 # type: ignore from google.longrunning import operations_pb2 # type: ignore diff --git a/google/cloud/firestore_v1/services/firestore/client.py b/google/cloud/firestore_v1/services/firestore/client.py index c7e414d35..ab8e76610 100644 --- a/google/cloud/firestore_v1/services/firestore/client.py +++ b/google/cloud/firestore_v1/services/firestore/client.py @@ -56,6 +56,7 @@ from google.cloud.firestore_v1.types import document as gf_document from google.cloud.firestore_v1.types import firestore from google.cloud.firestore_v1.types import query +from google.cloud.firestore_v1.types import query_profile from google.cloud.firestore_v1.types import write as gf_write from google.cloud.location import locations_pb2 # type: ignore from google.longrunning import operations_pb2 # type: ignore diff --git a/google/cloud/firestore_v1/types/__init__.py b/google/cloud/firestore_v1/types/__init__.py index bbca937f7..433c8a012 100644 --- a/google/cloud/firestore_v1/types/__init__.py +++ b/google/cloud/firestore_v1/types/__init__.py @@ -67,6 +67,12 @@ StructuredAggregationQuery, StructuredQuery, ) +from .query_profile import ( + ExecutionStats, + ExplainMetrics, + ExplainOptions, + PlanSummary, +) from .write import ( DocumentChange, DocumentDelete, @@ -120,6 +126,10 @@ "Cursor", "StructuredAggregationQuery", "StructuredQuery", + "ExecutionStats", + "ExplainMetrics", + "ExplainOptions", + "PlanSummary", "DocumentChange", "DocumentDelete", "DocumentRemove", diff --git a/google/cloud/firestore_v1/types/firestore.py b/google/cloud/firestore_v1/types/firestore.py index 7b542a8c4..22388676f 100644 --- a/google/cloud/firestore_v1/types/firestore.py +++ b/google/cloud/firestore_v1/types/firestore.py @@ -23,6 +23,7 @@ from google.cloud.firestore_v1.types import common from google.cloud.firestore_v1.types import document as gf_document from google.cloud.firestore_v1.types import query as gf_query +from google.cloud.firestore_v1.types import query_profile from google.cloud.firestore_v1.types import write from google.protobuf import timestamp_pb2 # type: ignore from google.protobuf import wrappers_pb2 # type: ignore @@ -720,6 +721,11 @@ class RunQueryRequest(proto.Message): minute timestamp within the past 7 days. This field is a member of `oneof`_ ``consistency_selector``. + explain_options (google.cloud.firestore_v1.types.ExplainOptions): + Optional. Explain options for the query. If + set, additional query statistics will be + returned. If not, only query results will be + returned. """ parent: str = proto.Field( @@ -749,6 +755,11 @@ class RunQueryRequest(proto.Message): oneof="consistency_selector", message=timestamp_pb2.Timestamp, ) + explain_options: query_profile.ExplainOptions = proto.Field( + proto.MESSAGE, + number=10, + message=query_profile.ExplainOptions, + ) class RunQueryResponse(proto.Message): @@ -787,6 +798,11 @@ class RunQueryResponse(proto.Message): returned. This field is a member of `oneof`_ ``continuation_selector``. + explain_metrics (google.cloud.firestore_v1.types.ExplainMetrics): + Query explain metrics. This is only present when the + [RunQueryRequest.explain_options][google.firestore.v1.RunQueryRequest.explain_options] + is provided, and it is sent only once with the last response + in the stream. """ transaction: bytes = proto.Field( @@ -812,6 +828,11 @@ class RunQueryResponse(proto.Message): number=6, oneof="continuation_selector", ) + explain_metrics: query_profile.ExplainMetrics = proto.Field( + proto.MESSAGE, + number=11, + message=query_profile.ExplainMetrics, + ) class RunAggregationQueryRequest(proto.Message): @@ -861,6 +882,11 @@ class RunAggregationQueryRequest(proto.Message): minute timestamp within the past 7 days. This field is a member of `oneof`_ ``consistency_selector``. + explain_options (google.cloud.firestore_v1.types.ExplainOptions): + Optional. Explain options for the query. If + set, additional query statistics will be + returned. If not, only query results will be + returned. """ parent: str = proto.Field( @@ -890,6 +916,11 @@ class RunAggregationQueryRequest(proto.Message): oneof="consistency_selector", message=timestamp_pb2.Timestamp, ) + explain_options: query_profile.ExplainOptions = proto.Field( + proto.MESSAGE, + number=8, + message=query_profile.ExplainOptions, + ) class RunAggregationQueryResponse(proto.Message): @@ -915,6 +946,11 @@ class RunAggregationQueryResponse(proto.Message): If the query returns no results, a response with ``read_time`` and no ``result`` will be sent, and this represents the time at which the query was run. + explain_metrics (google.cloud.firestore_v1.types.ExplainMetrics): + Query explain metrics. This is only present when the + [RunAggregationQueryRequest.explain_options][google.firestore.v1.RunAggregationQueryRequest.explain_options] + is provided, and it is sent only once with the last response + in the stream. """ result: aggregation_result.AggregationResult = proto.Field( @@ -931,6 +967,11 @@ class RunAggregationQueryResponse(proto.Message): number=3, message=timestamp_pb2.Timestamp, ) + explain_metrics: query_profile.ExplainMetrics = proto.Field( + proto.MESSAGE, + number=10, + message=query_profile.ExplainMetrics, + ) class PartitionQueryRequest(proto.Message): diff --git a/google/cloud/firestore_v1/types/query.py b/google/cloud/firestore_v1/types/query.py index fa01c3569..b6a5949e4 100644 --- a/google/cloud/firestore_v1/types/query.py +++ b/google/cloud/firestore_v1/types/query.py @@ -152,6 +152,13 @@ class StructuredQuery(proto.Message): - The value must be greater than or equal to zero if specified. + find_nearest (google.cloud.firestore_v1.types.StructuredQuery.FindNearest): + Optional. A potential Nearest Neighbors + Search. + Applies after all other filters and ordering. + + Finds the closest vector embeddings to the given + query vector. """ class Direction(proto.Enum): @@ -512,6 +519,78 @@ class Projection(proto.Message): message="StructuredQuery.FieldReference", ) + class FindNearest(proto.Message): + r"""Nearest Neighbors search config. + + Attributes: + vector_field (google.cloud.firestore_v1.types.StructuredQuery.FieldReference): + Required. An indexed vector field to search upon. Only + documents which contain vectors whose dimensionality match + the query_vector can be returned. + query_vector (google.cloud.firestore_v1.types.Value): + Required. The query vector that we are + searching on. Must be a vector of no more than + 2048 dimensions. + distance_measure (google.cloud.firestore_v1.types.StructuredQuery.FindNearest.DistanceMeasure): + Required. The Distance Measure to use, + required. + limit (google.protobuf.wrappers_pb2.Int32Value): + Required. The number of nearest neighbors to + return. Must be a positive integer of no more + than 1000. + """ + + class DistanceMeasure(proto.Enum): + r"""The distance measure to use when comparing vectors. + + Values: + DISTANCE_MEASURE_UNSPECIFIED (0): + Should not be set. + EUCLIDEAN (1): + Measures the EUCLIDEAN distance between the vectors. See + `Euclidean `__ + to learn more + COSINE (2): + Compares vectors based on the angle between them, which + allows you to measure similarity that isn't based on the + vectors magnitude. We recommend using DOT_PRODUCT with unit + normalized vectors instead of COSINE distance, which is + mathematically equivalent with better performance. See + `Cosine + Similarity `__ + to learn more. + DOT_PRODUCT (3): + Similar to cosine but is affected by the magnitude of the + vectors. See `Dot + Product `__ to + learn more. + """ + DISTANCE_MEASURE_UNSPECIFIED = 0 + EUCLIDEAN = 1 + COSINE = 2 + DOT_PRODUCT = 3 + + vector_field: "StructuredQuery.FieldReference" = proto.Field( + proto.MESSAGE, + number=1, + message="StructuredQuery.FieldReference", + ) + query_vector: document.Value = proto.Field( + proto.MESSAGE, + number=2, + message=document.Value, + ) + distance_measure: "StructuredQuery.FindNearest.DistanceMeasure" = proto.Field( + proto.ENUM, + number=3, + enum="StructuredQuery.FindNearest.DistanceMeasure", + ) + limit: wrappers_pb2.Int32Value = proto.Field( + proto.MESSAGE, + number=4, + message=wrappers_pb2.Int32Value, + ) + select: Projection = proto.Field( proto.MESSAGE, number=1, @@ -551,6 +630,11 @@ class Projection(proto.Message): number=5, message=wrappers_pb2.Int32Value, ) + find_nearest: FindNearest = proto.Field( + proto.MESSAGE, + number=9, + message=FindNearest, + ) class StructuredAggregationQuery(proto.Message): diff --git a/google/cloud/firestore_v1/types/query_profile.py b/google/cloud/firestore_v1/types/query_profile.py new file mode 100644 index 000000000..0b26236cf --- /dev/null +++ b/google/cloud/firestore_v1/types/query_profile.py @@ -0,0 +1,144 @@ +# -*- coding: utf-8 -*- +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from __future__ import annotations + +from typing import MutableMapping, MutableSequence + +import proto # type: ignore + +from google.protobuf import duration_pb2 # type: ignore +from google.protobuf import struct_pb2 # type: ignore + + +__protobuf__ = proto.module( + package="google.firestore.v1", + manifest={ + "ExplainOptions", + "ExplainMetrics", + "PlanSummary", + "ExecutionStats", + }, +) + + +class ExplainOptions(proto.Message): + r"""Explain options for the query. + + Attributes: + analyze (bool): + Optional. Whether to execute this query. + + When false (the default), the query will be + planned, returning only metrics from the + planning stages. + + When true, the query will be planned and + executed, returning the full query results along + with both planning and execution stage metrics. + """ + + analyze: bool = proto.Field( + proto.BOOL, + number=1, + ) + + +class ExplainMetrics(proto.Message): + r"""Explain metrics for the query. + + Attributes: + plan_summary (google.cloud.firestore_v1.types.PlanSummary): + Planning phase information for the query. + execution_stats (google.cloud.firestore_v1.types.ExecutionStats): + Aggregated stats from the execution of the query. Only + present when + [ExplainOptions.analyze][google.firestore.v1.ExplainOptions.analyze] + is set to true. + """ + + plan_summary: "PlanSummary" = proto.Field( + proto.MESSAGE, + number=1, + message="PlanSummary", + ) + execution_stats: "ExecutionStats" = proto.Field( + proto.MESSAGE, + number=2, + message="ExecutionStats", + ) + + +class PlanSummary(proto.Message): + r"""Planning phase information for the query. + + Attributes: + indexes_used (MutableSequence[google.protobuf.struct_pb2.Struct]): + The indexes selected for the query. For example: [ + {"query_scope": "Collection", "properties": "(foo ASC, + **name** ASC)"}, {"query_scope": "Collection", "properties": + "(bar ASC, **name** ASC)"} ] + """ + + indexes_used: MutableSequence[struct_pb2.Struct] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=struct_pb2.Struct, + ) + + +class ExecutionStats(proto.Message): + r"""Execution statistics for the query. + + Attributes: + results_returned (int): + Total number of results returned, including + documents, projections, aggregation results, + keys. + execution_duration (google.protobuf.duration_pb2.Duration): + Total time to execute the query in the + backend. + read_operations (int): + Total billable read operations. + debug_stats (google.protobuf.struct_pb2.Struct): + Debugging statistics from the execution of the query. Note + that the debugging stats are subject to change as Firestore + evolves. It could include: { "indexes_entries_scanned": + "1000", "documents_scanned": "20", "billing_details" : { + "documents_billable": "20", "index_entries_billable": + "1000", "min_query_cost": "0" } } + """ + + results_returned: int = proto.Field( + proto.INT64, + number=1, + ) + execution_duration: duration_pb2.Duration = proto.Field( + proto.MESSAGE, + number=3, + message=duration_pb2.Duration, + ) + read_operations: int = proto.Field( + proto.INT64, + number=4, + ) + debug_stats: struct_pb2.Struct = proto.Field( + proto.MESSAGE, + number=5, + message=struct_pb2.Struct, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/scripts/fixup_firestore_admin_v1_keywords.py b/scripts/fixup_firestore_admin_v1_keywords.py index a4caa0c67..85cad9a31 100644 --- a/scripts/fixup_firestore_admin_v1_keywords.py +++ b/scripts/fixup_firestore_admin_v1_keywords.py @@ -45,18 +45,27 @@ def partition( class firestore_adminCallTransformer(cst.CSTTransformer): CTRL_PARAMS: Tuple[str] = ('retry', 'timeout', 'metadata') METHOD_TO_PARAMS: Dict[str, Tuple[str]] = { + 'create_backup_schedule': ('parent', 'backup_schedule', ), 'create_database': ('parent', 'database', 'database_id', ), 'create_index': ('parent', 'index', ), + 'delete_backup': ('name', ), + 'delete_backup_schedule': ('name', ), 'delete_database': ('name', 'etag', ), 'delete_index': ('name', ), 'export_documents': ('name', 'collection_ids', 'output_uri_prefix', 'namespace_ids', 'snapshot_time', ), + 'get_backup': ('name', ), + 'get_backup_schedule': ('name', ), 'get_database': ('name', ), 'get_field': ('name', ), 'get_index': ('name', ), 'import_documents': ('name', 'collection_ids', 'input_uri_prefix', 'namespace_ids', ), + 'list_backups': ('parent', ), + 'list_backup_schedules': ('parent', ), 'list_databases': ('parent', ), 'list_fields': ('parent', 'filter', 'page_size', 'page_token', ), 'list_indexes': ('parent', 'filter', 'page_size', 'page_token', ), + 'restore_database': ('parent', 'database_id', 'backup', ), + 'update_backup_schedule': ('backup_schedule', 'update_mask', ), 'update_database': ('database', 'update_mask', ), 'update_field': ('field', 'update_mask', ), } diff --git a/scripts/fixup_firestore_v1_keywords.py b/scripts/fixup_firestore_v1_keywords.py index aa39e7316..5798fe0ab 100644 --- a/scripts/fixup_firestore_v1_keywords.py +++ b/scripts/fixup_firestore_v1_keywords.py @@ -57,8 +57,8 @@ class firestoreCallTransformer(cst.CSTTransformer): 'listen': ('database', 'add_target', 'remove_target', 'labels', ), 'partition_query': ('parent', 'structured_query', 'partition_count', 'page_token', 'page_size', 'read_time', ), 'rollback': ('database', 'transaction', ), - 'run_aggregation_query': ('parent', 'structured_aggregation_query', 'transaction', 'new_transaction', 'read_time', ), - 'run_query': ('parent', 'structured_query', 'transaction', 'new_transaction', 'read_time', ), + 'run_aggregation_query': ('parent', 'structured_aggregation_query', 'transaction', 'new_transaction', 'read_time', 'explain_options', ), + 'run_query': ('parent', 'structured_query', 'transaction', 'new_transaction', 'read_time', 'explain_options', ), 'update_document': ('document', 'update_mask', 'mask', 'current_document', ), 'write': ('database', 'stream_id', 'writes', 'stream_token', 'labels', ), } diff --git a/tests/unit/gapic/firestore_admin_v1/test_firestore_admin.py b/tests/unit/gapic/firestore_admin_v1/test_firestore_admin.py index 62f928871..f2cada543 100644 --- a/tests/unit/gapic/firestore_admin_v1/test_firestore_admin.py +++ b/tests/unit/gapic/firestore_admin_v1/test_firestore_admin.py @@ -57,6 +57,7 @@ ) from google.cloud.firestore_admin_v1.services.firestore_admin import pagers from google.cloud.firestore_admin_v1.services.firestore_admin import transports +from google.cloud.firestore_admin_v1.types import backup from google.cloud.firestore_admin_v1.types import database from google.cloud.firestore_admin_v1.types import database as gfa_database from google.cloud.firestore_admin_v1.types import field @@ -65,6 +66,7 @@ from google.cloud.firestore_admin_v1.types import index from google.cloud.firestore_admin_v1.types import index as gfa_index from google.cloud.firestore_admin_v1.types import operation as gfa_operation +from google.cloud.firestore_admin_v1.types import schedule from google.cloud.location import locations_pb2 from google.longrunning import operations_pb2 # type: ignore from google.oauth2 import service_account @@ -72,6 +74,7 @@ from google.protobuf import empty_pb2 # type: ignore from google.protobuf import field_mask_pb2 # type: ignore from google.protobuf import timestamp_pb2 # type: ignore +from google.type import dayofweek_pb2 # type: ignore import google.auth @@ -4811,6 +4814,2079 @@ async def test_delete_database_flattened_error_async(): ) +@pytest.mark.parametrize( + "request_type", + [ + firestore_admin.GetBackupRequest, + dict, + ], +) +def test_get_backup(request_type, transport: str = "grpc"): + client = FirestoreAdminClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_backup), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = backup.Backup( + name="name_value", + database="database_value", + database_uid="database_uid_value", + state=backup.Backup.State.CREATING, + ) + response = client.get_backup(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == firestore_admin.GetBackupRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, backup.Backup) + assert response.name == "name_value" + assert response.database == "database_value" + assert response.database_uid == "database_uid_value" + assert response.state == backup.Backup.State.CREATING + + +def test_get_backup_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = FirestoreAdminClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_backup), "__call__") as call: + client.get_backup() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == firestore_admin.GetBackupRequest() + + +@pytest.mark.asyncio +async def test_get_backup_async( + transport: str = "grpc_asyncio", request_type=firestore_admin.GetBackupRequest +): + client = FirestoreAdminAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_backup), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + backup.Backup( + name="name_value", + database="database_value", + database_uid="database_uid_value", + state=backup.Backup.State.CREATING, + ) + ) + response = await client.get_backup(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == firestore_admin.GetBackupRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, backup.Backup) + assert response.name == "name_value" + assert response.database == "database_value" + assert response.database_uid == "database_uid_value" + assert response.state == backup.Backup.State.CREATING + + +@pytest.mark.asyncio +async def test_get_backup_async_from_dict(): + await test_get_backup_async(request_type=dict) + + +def test_get_backup_field_headers(): + client = FirestoreAdminClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = firestore_admin.GetBackupRequest() + + request.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_backup), "__call__") as call: + call.return_value = backup.Backup() + client.get_backup(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=name_value", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_get_backup_field_headers_async(): + client = FirestoreAdminAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = firestore_admin.GetBackupRequest() + + request.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_backup), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(backup.Backup()) + await client.get_backup(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=name_value", + ) in kw["metadata"] + + +def test_get_backup_flattened(): + client = FirestoreAdminClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_backup), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = backup.Backup() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.get_backup( + name="name_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val + + +def test_get_backup_flattened_error(): + client = FirestoreAdminClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.get_backup( + firestore_admin.GetBackupRequest(), + name="name_value", + ) + + +@pytest.mark.asyncio +async def test_get_backup_flattened_async(): + client = FirestoreAdminAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_backup), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = backup.Backup() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(backup.Backup()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.get_backup( + name="name_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_get_backup_flattened_error_async(): + client = FirestoreAdminAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.get_backup( + firestore_admin.GetBackupRequest(), + name="name_value", + ) + + +@pytest.mark.parametrize( + "request_type", + [ + firestore_admin.ListBackupsRequest, + dict, + ], +) +def test_list_backups(request_type, transport: str = "grpc"): + client = FirestoreAdminClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_backups), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = firestore_admin.ListBackupsResponse( + unreachable=["unreachable_value"], + ) + response = client.list_backups(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == firestore_admin.ListBackupsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, firestore_admin.ListBackupsResponse) + assert response.unreachable == ["unreachable_value"] + + +def test_list_backups_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = FirestoreAdminClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_backups), "__call__") as call: + client.list_backups() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == firestore_admin.ListBackupsRequest() + + +@pytest.mark.asyncio +async def test_list_backups_async( + transport: str = "grpc_asyncio", request_type=firestore_admin.ListBackupsRequest +): + client = FirestoreAdminAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_backups), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + firestore_admin.ListBackupsResponse( + unreachable=["unreachable_value"], + ) + ) + response = await client.list_backups(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == firestore_admin.ListBackupsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, firestore_admin.ListBackupsResponse) + assert response.unreachable == ["unreachable_value"] + + +@pytest.mark.asyncio +async def test_list_backups_async_from_dict(): + await test_list_backups_async(request_type=dict) + + +def test_list_backups_field_headers(): + client = FirestoreAdminClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = firestore_admin.ListBackupsRequest() + + request.parent = "parent_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_backups), "__call__") as call: + call.return_value = firestore_admin.ListBackupsResponse() + client.list_backups(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "parent=parent_value", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_list_backups_field_headers_async(): + client = FirestoreAdminAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = firestore_admin.ListBackupsRequest() + + request.parent = "parent_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_backups), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + firestore_admin.ListBackupsResponse() + ) + await client.list_backups(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "parent=parent_value", + ) in kw["metadata"] + + +def test_list_backups_flattened(): + client = FirestoreAdminClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_backups), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = firestore_admin.ListBackupsResponse() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.list_backups( + parent="parent_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + + +def test_list_backups_flattened_error(): + client = FirestoreAdminClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_backups( + firestore_admin.ListBackupsRequest(), + parent="parent_value", + ) + + +@pytest.mark.asyncio +async def test_list_backups_flattened_async(): + client = FirestoreAdminAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_backups), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = firestore_admin.ListBackupsResponse() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + firestore_admin.ListBackupsResponse() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.list_backups( + parent="parent_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_list_backups_flattened_error_async(): + client = FirestoreAdminAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.list_backups( + firestore_admin.ListBackupsRequest(), + parent="parent_value", + ) + + +@pytest.mark.parametrize( + "request_type", + [ + firestore_admin.DeleteBackupRequest, + dict, + ], +) +def test_delete_backup(request_type, transport: str = "grpc"): + client = FirestoreAdminClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.delete_backup), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = None + response = client.delete_backup(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == firestore_admin.DeleteBackupRequest() + + # Establish that the response is the type that we expect. + assert response is None + + +def test_delete_backup_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = FirestoreAdminClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.delete_backup), "__call__") as call: + client.delete_backup() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == firestore_admin.DeleteBackupRequest() + + +@pytest.mark.asyncio +async def test_delete_backup_async( + transport: str = "grpc_asyncio", request_type=firestore_admin.DeleteBackupRequest +): + client = FirestoreAdminAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.delete_backup), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + response = await client.delete_backup(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == firestore_admin.DeleteBackupRequest() + + # Establish that the response is the type that we expect. + assert response is None + + +@pytest.mark.asyncio +async def test_delete_backup_async_from_dict(): + await test_delete_backup_async(request_type=dict) + + +def test_delete_backup_field_headers(): + client = FirestoreAdminClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = firestore_admin.DeleteBackupRequest() + + request.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.delete_backup), "__call__") as call: + call.return_value = None + client.delete_backup(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=name_value", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_delete_backup_field_headers_async(): + client = FirestoreAdminAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = firestore_admin.DeleteBackupRequest() + + request.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.delete_backup), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + await client.delete_backup(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=name_value", + ) in kw["metadata"] + + +def test_delete_backup_flattened(): + client = FirestoreAdminClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.delete_backup), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = None + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.delete_backup( + name="name_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val + + +def test_delete_backup_flattened_error(): + client = FirestoreAdminClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.delete_backup( + firestore_admin.DeleteBackupRequest(), + name="name_value", + ) + + +@pytest.mark.asyncio +async def test_delete_backup_flattened_async(): + client = FirestoreAdminAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.delete_backup), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = None + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.delete_backup( + name="name_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_delete_backup_flattened_error_async(): + client = FirestoreAdminAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.delete_backup( + firestore_admin.DeleteBackupRequest(), + name="name_value", + ) + + +@pytest.mark.parametrize( + "request_type", + [ + firestore_admin.RestoreDatabaseRequest, + dict, + ], +) +def test_restore_database(request_type, transport: str = "grpc"): + client = FirestoreAdminClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.restore_database), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name="operations/spam") + response = client.restore_database(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == firestore_admin.RestoreDatabaseRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +def test_restore_database_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = FirestoreAdminClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.restore_database), "__call__") as call: + client.restore_database() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == firestore_admin.RestoreDatabaseRequest() + + +@pytest.mark.asyncio +async def test_restore_database_async( + transport: str = "grpc_asyncio", request_type=firestore_admin.RestoreDatabaseRequest +): + client = FirestoreAdminAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.restore_database), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + response = await client.restore_database(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == firestore_admin.RestoreDatabaseRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +@pytest.mark.asyncio +async def test_restore_database_async_from_dict(): + await test_restore_database_async(request_type=dict) + + +def test_restore_database_field_headers(): + client = FirestoreAdminClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = firestore_admin.RestoreDatabaseRequest() + + request.parent = "parent_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.restore_database), "__call__") as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.restore_database(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "parent=parent_value", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_restore_database_field_headers_async(): + client = FirestoreAdminAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = firestore_admin.RestoreDatabaseRequest() + + request.parent = "parent_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.restore_database), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/op") + ) + await client.restore_database(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "parent=parent_value", + ) in kw["metadata"] + + +@pytest.mark.parametrize( + "request_type", + [ + firestore_admin.CreateBackupScheduleRequest, + dict, + ], +) +def test_create_backup_schedule(request_type, transport: str = "grpc"): + client = FirestoreAdminClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_backup_schedule), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = schedule.BackupSchedule( + name="name_value", + ) + response = client.create_backup_schedule(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == firestore_admin.CreateBackupScheduleRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, schedule.BackupSchedule) + assert response.name == "name_value" + + +def test_create_backup_schedule_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = FirestoreAdminClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_backup_schedule), "__call__" + ) as call: + client.create_backup_schedule() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == firestore_admin.CreateBackupScheduleRequest() + + +@pytest.mark.asyncio +async def test_create_backup_schedule_async( + transport: str = "grpc_asyncio", + request_type=firestore_admin.CreateBackupScheduleRequest, +): + client = FirestoreAdminAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_backup_schedule), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + schedule.BackupSchedule( + name="name_value", + ) + ) + response = await client.create_backup_schedule(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == firestore_admin.CreateBackupScheduleRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, schedule.BackupSchedule) + assert response.name == "name_value" + + +@pytest.mark.asyncio +async def test_create_backup_schedule_async_from_dict(): + await test_create_backup_schedule_async(request_type=dict) + + +def test_create_backup_schedule_field_headers(): + client = FirestoreAdminClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = firestore_admin.CreateBackupScheduleRequest() + + request.parent = "parent_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_backup_schedule), "__call__" + ) as call: + call.return_value = schedule.BackupSchedule() + client.create_backup_schedule(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "parent=parent_value", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_create_backup_schedule_field_headers_async(): + client = FirestoreAdminAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = firestore_admin.CreateBackupScheduleRequest() + + request.parent = "parent_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_backup_schedule), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + schedule.BackupSchedule() + ) + await client.create_backup_schedule(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "parent=parent_value", + ) in kw["metadata"] + + +def test_create_backup_schedule_flattened(): + client = FirestoreAdminClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_backup_schedule), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = schedule.BackupSchedule() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.create_backup_schedule( + parent="parent_value", + backup_schedule=schedule.BackupSchedule(name="name_value"), + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].backup_schedule + mock_val = schedule.BackupSchedule(name="name_value") + assert arg == mock_val + + +def test_create_backup_schedule_flattened_error(): + client = FirestoreAdminClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.create_backup_schedule( + firestore_admin.CreateBackupScheduleRequest(), + parent="parent_value", + backup_schedule=schedule.BackupSchedule(name="name_value"), + ) + + +@pytest.mark.asyncio +async def test_create_backup_schedule_flattened_async(): + client = FirestoreAdminAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_backup_schedule), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = schedule.BackupSchedule() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + schedule.BackupSchedule() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.create_backup_schedule( + parent="parent_value", + backup_schedule=schedule.BackupSchedule(name="name_value"), + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + arg = args[0].backup_schedule + mock_val = schedule.BackupSchedule(name="name_value") + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_create_backup_schedule_flattened_error_async(): + client = FirestoreAdminAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.create_backup_schedule( + firestore_admin.CreateBackupScheduleRequest(), + parent="parent_value", + backup_schedule=schedule.BackupSchedule(name="name_value"), + ) + + +@pytest.mark.parametrize( + "request_type", + [ + firestore_admin.GetBackupScheduleRequest, + dict, + ], +) +def test_get_backup_schedule(request_type, transport: str = "grpc"): + client = FirestoreAdminClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_backup_schedule), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = schedule.BackupSchedule( + name="name_value", + ) + response = client.get_backup_schedule(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == firestore_admin.GetBackupScheduleRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, schedule.BackupSchedule) + assert response.name == "name_value" + + +def test_get_backup_schedule_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = FirestoreAdminClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_backup_schedule), "__call__" + ) as call: + client.get_backup_schedule() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == firestore_admin.GetBackupScheduleRequest() + + +@pytest.mark.asyncio +async def test_get_backup_schedule_async( + transport: str = "grpc_asyncio", + request_type=firestore_admin.GetBackupScheduleRequest, +): + client = FirestoreAdminAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_backup_schedule), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + schedule.BackupSchedule( + name="name_value", + ) + ) + response = await client.get_backup_schedule(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == firestore_admin.GetBackupScheduleRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, schedule.BackupSchedule) + assert response.name == "name_value" + + +@pytest.mark.asyncio +async def test_get_backup_schedule_async_from_dict(): + await test_get_backup_schedule_async(request_type=dict) + + +def test_get_backup_schedule_field_headers(): + client = FirestoreAdminClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = firestore_admin.GetBackupScheduleRequest() + + request.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_backup_schedule), "__call__" + ) as call: + call.return_value = schedule.BackupSchedule() + client.get_backup_schedule(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=name_value", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_get_backup_schedule_field_headers_async(): + client = FirestoreAdminAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = firestore_admin.GetBackupScheduleRequest() + + request.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_backup_schedule), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + schedule.BackupSchedule() + ) + await client.get_backup_schedule(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=name_value", + ) in kw["metadata"] + + +def test_get_backup_schedule_flattened(): + client = FirestoreAdminClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_backup_schedule), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = schedule.BackupSchedule() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.get_backup_schedule( + name="name_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val + + +def test_get_backup_schedule_flattened_error(): + client = FirestoreAdminClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.get_backup_schedule( + firestore_admin.GetBackupScheduleRequest(), + name="name_value", + ) + + +@pytest.mark.asyncio +async def test_get_backup_schedule_flattened_async(): + client = FirestoreAdminAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_backup_schedule), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = schedule.BackupSchedule() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + schedule.BackupSchedule() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.get_backup_schedule( + name="name_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_get_backup_schedule_flattened_error_async(): + client = FirestoreAdminAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.get_backup_schedule( + firestore_admin.GetBackupScheduleRequest(), + name="name_value", + ) + + +@pytest.mark.parametrize( + "request_type", + [ + firestore_admin.ListBackupSchedulesRequest, + dict, + ], +) +def test_list_backup_schedules(request_type, transport: str = "grpc"): + client = FirestoreAdminClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_backup_schedules), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = firestore_admin.ListBackupSchedulesResponse() + response = client.list_backup_schedules(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == firestore_admin.ListBackupSchedulesRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, firestore_admin.ListBackupSchedulesResponse) + + +def test_list_backup_schedules_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = FirestoreAdminClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_backup_schedules), "__call__" + ) as call: + client.list_backup_schedules() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == firestore_admin.ListBackupSchedulesRequest() + + +@pytest.mark.asyncio +async def test_list_backup_schedules_async( + transport: str = "grpc_asyncio", + request_type=firestore_admin.ListBackupSchedulesRequest, +): + client = FirestoreAdminAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_backup_schedules), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + firestore_admin.ListBackupSchedulesResponse() + ) + response = await client.list_backup_schedules(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == firestore_admin.ListBackupSchedulesRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, firestore_admin.ListBackupSchedulesResponse) + + +@pytest.mark.asyncio +async def test_list_backup_schedules_async_from_dict(): + await test_list_backup_schedules_async(request_type=dict) + + +def test_list_backup_schedules_field_headers(): + client = FirestoreAdminClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = firestore_admin.ListBackupSchedulesRequest() + + request.parent = "parent_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_backup_schedules), "__call__" + ) as call: + call.return_value = firestore_admin.ListBackupSchedulesResponse() + client.list_backup_schedules(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "parent=parent_value", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_list_backup_schedules_field_headers_async(): + client = FirestoreAdminAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = firestore_admin.ListBackupSchedulesRequest() + + request.parent = "parent_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_backup_schedules), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + firestore_admin.ListBackupSchedulesResponse() + ) + await client.list_backup_schedules(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "parent=parent_value", + ) in kw["metadata"] + + +def test_list_backup_schedules_flattened(): + client = FirestoreAdminClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_backup_schedules), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = firestore_admin.ListBackupSchedulesResponse() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.list_backup_schedules( + parent="parent_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + + +def test_list_backup_schedules_flattened_error(): + client = FirestoreAdminClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_backup_schedules( + firestore_admin.ListBackupSchedulesRequest(), + parent="parent_value", + ) + + +@pytest.mark.asyncio +async def test_list_backup_schedules_flattened_async(): + client = FirestoreAdminAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_backup_schedules), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = firestore_admin.ListBackupSchedulesResponse() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + firestore_admin.ListBackupSchedulesResponse() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.list_backup_schedules( + parent="parent_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].parent + mock_val = "parent_value" + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_list_backup_schedules_flattened_error_async(): + client = FirestoreAdminAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.list_backup_schedules( + firestore_admin.ListBackupSchedulesRequest(), + parent="parent_value", + ) + + +@pytest.mark.parametrize( + "request_type", + [ + firestore_admin.UpdateBackupScheduleRequest, + dict, + ], +) +def test_update_backup_schedule(request_type, transport: str = "grpc"): + client = FirestoreAdminClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_backup_schedule), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = schedule.BackupSchedule( + name="name_value", + ) + response = client.update_backup_schedule(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == firestore_admin.UpdateBackupScheduleRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, schedule.BackupSchedule) + assert response.name == "name_value" + + +def test_update_backup_schedule_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = FirestoreAdminClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_backup_schedule), "__call__" + ) as call: + client.update_backup_schedule() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == firestore_admin.UpdateBackupScheduleRequest() + + +@pytest.mark.asyncio +async def test_update_backup_schedule_async( + transport: str = "grpc_asyncio", + request_type=firestore_admin.UpdateBackupScheduleRequest, +): + client = FirestoreAdminAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_backup_schedule), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + schedule.BackupSchedule( + name="name_value", + ) + ) + response = await client.update_backup_schedule(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == firestore_admin.UpdateBackupScheduleRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, schedule.BackupSchedule) + assert response.name == "name_value" + + +@pytest.mark.asyncio +async def test_update_backup_schedule_async_from_dict(): + await test_update_backup_schedule_async(request_type=dict) + + +def test_update_backup_schedule_field_headers(): + client = FirestoreAdminClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = firestore_admin.UpdateBackupScheduleRequest() + + request.backup_schedule.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_backup_schedule), "__call__" + ) as call: + call.return_value = schedule.BackupSchedule() + client.update_backup_schedule(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "backup_schedule.name=name_value", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_update_backup_schedule_field_headers_async(): + client = FirestoreAdminAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = firestore_admin.UpdateBackupScheduleRequest() + + request.backup_schedule.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_backup_schedule), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + schedule.BackupSchedule() + ) + await client.update_backup_schedule(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "backup_schedule.name=name_value", + ) in kw["metadata"] + + +def test_update_backup_schedule_flattened(): + client = FirestoreAdminClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_backup_schedule), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = schedule.BackupSchedule() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.update_backup_schedule( + backup_schedule=schedule.BackupSchedule(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].backup_schedule + mock_val = schedule.BackupSchedule(name="name_value") + assert arg == mock_val + arg = args[0].update_mask + mock_val = field_mask_pb2.FieldMask(paths=["paths_value"]) + assert arg == mock_val + + +def test_update_backup_schedule_flattened_error(): + client = FirestoreAdminClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.update_backup_schedule( + firestore_admin.UpdateBackupScheduleRequest(), + backup_schedule=schedule.BackupSchedule(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + + +@pytest.mark.asyncio +async def test_update_backup_schedule_flattened_async(): + client = FirestoreAdminAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_backup_schedule), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = schedule.BackupSchedule() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + schedule.BackupSchedule() + ) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.update_backup_schedule( + backup_schedule=schedule.BackupSchedule(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].backup_schedule + mock_val = schedule.BackupSchedule(name="name_value") + assert arg == mock_val + arg = args[0].update_mask + mock_val = field_mask_pb2.FieldMask(paths=["paths_value"]) + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_update_backup_schedule_flattened_error_async(): + client = FirestoreAdminAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.update_backup_schedule( + firestore_admin.UpdateBackupScheduleRequest(), + backup_schedule=schedule.BackupSchedule(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), + ) + + +@pytest.mark.parametrize( + "request_type", + [ + firestore_admin.DeleteBackupScheduleRequest, + dict, + ], +) +def test_delete_backup_schedule(request_type, transport: str = "grpc"): + client = FirestoreAdminClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_backup_schedule), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = None + response = client.delete_backup_schedule(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == firestore_admin.DeleteBackupScheduleRequest() + + # Establish that the response is the type that we expect. + assert response is None + + +def test_delete_backup_schedule_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = FirestoreAdminClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_backup_schedule), "__call__" + ) as call: + client.delete_backup_schedule() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == firestore_admin.DeleteBackupScheduleRequest() + + +@pytest.mark.asyncio +async def test_delete_backup_schedule_async( + transport: str = "grpc_asyncio", + request_type=firestore_admin.DeleteBackupScheduleRequest, +): + client = FirestoreAdminAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_backup_schedule), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + response = await client.delete_backup_schedule(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == firestore_admin.DeleteBackupScheduleRequest() + + # Establish that the response is the type that we expect. + assert response is None + + +@pytest.mark.asyncio +async def test_delete_backup_schedule_async_from_dict(): + await test_delete_backup_schedule_async(request_type=dict) + + +def test_delete_backup_schedule_field_headers(): + client = FirestoreAdminClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = firestore_admin.DeleteBackupScheduleRequest() + + request.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_backup_schedule), "__call__" + ) as call: + call.return_value = None + client.delete_backup_schedule(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=name_value", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_delete_backup_schedule_field_headers_async(): + client = FirestoreAdminAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = firestore_admin.DeleteBackupScheduleRequest() + + request.name = "name_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_backup_schedule), "__call__" + ) as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + await client.delete_backup_schedule(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "name=name_value", + ) in kw["metadata"] + + +def test_delete_backup_schedule_flattened(): + client = FirestoreAdminClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_backup_schedule), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = None + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.delete_backup_schedule( + name="name_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val + + +def test_delete_backup_schedule_flattened_error(): + client = FirestoreAdminClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.delete_backup_schedule( + firestore_admin.DeleteBackupScheduleRequest(), + name="name_value", + ) + + +@pytest.mark.asyncio +async def test_delete_backup_schedule_flattened_async(): + client = FirestoreAdminAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_backup_schedule), "__call__" + ) as call: + # Designate an appropriate return value for the call. + call.return_value = None + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.delete_backup_schedule( + name="name_value", + ) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + arg = args[0].name + mock_val = "name_value" + assert arg == mock_val + + +@pytest.mark.asyncio +async def test_delete_backup_schedule_flattened_error_async(): + client = FirestoreAdminAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + await client.delete_backup_schedule( + firestore_admin.DeleteBackupScheduleRequest(), + name="name_value", + ) + + @pytest.mark.parametrize( "request_type", [ @@ -4818,29 +6894,2763 @@ async def test_delete_database_flattened_error_async(): dict, ], ) -def test_create_index_rest(request_type): +def test_create_index_rest(request_type): + client = FirestoreAdminClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = { + "parent": "projects/sample1/databases/sample2/collectionGroups/sample3" + } + request_init["index"] = { + "name": "name_value", + "query_scope": 1, + "api_scope": 1, + "fields": [{"field_path": "field_path_value", "order": 1, "array_config": 1}], + "state": 1, + } + # The version of a generated dependency at test runtime may differ from the version used during generation. + # Delete any fields which are not present in the current runtime dependency + # See https://github.com/googleapis/gapic-generator-python/issues/1748 + + # Determine if the message type is proto-plus or protobuf + test_field = firestore_admin.CreateIndexRequest.meta.fields["index"] + + def get_message_fields(field): + # Given a field which is a message (composite type), return a list with + # all the fields of the message. + # If the field is not a composite type, return an empty list. + message_fields = [] + + if hasattr(field, "message") and field.message: + is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + + if is_field_type_proto_plus_type: + message_fields = field.message.meta.fields.values() + # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types + else: # pragma: NO COVER + message_fields = field.message.DESCRIPTOR.fields + return message_fields + + runtime_nested_fields = [ + (field.name, nested_field.name) + for field in get_message_fields(test_field) + for nested_field in get_message_fields(field) + ] + + subfields_not_in_runtime = [] + + # For each item in the sample request, create a list of sub fields which are not present at runtime + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for field, value in request_init["index"].items(): # pragma: NO COVER + result = None + is_repeated = False + # For repeated fields + if isinstance(value, list) and len(value): + is_repeated = True + result = value[0] + # For fields where the type is another message + if isinstance(value, dict): + result = value + + if result and hasattr(result, "keys"): + for subfield in result.keys(): + if (field, subfield) not in runtime_nested_fields: + subfields_not_in_runtime.append( + { + "field": field, + "subfield": subfield, + "is_repeated": is_repeated, + } + ) + + # Remove fields from the sample request which are not present in the runtime version of the dependency + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER + field = subfield_to_delete.get("field") + field_repeated = subfield_to_delete.get("is_repeated") + subfield = subfield_to_delete.get("subfield") + if subfield: + if field_repeated: + for i in range(0, len(request_init["index"][field])): + del request_init["index"][field][i][subfield] + else: + del request_init["index"][field][subfield] + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.create_index(request) + + # Establish that the response is the type that we expect. + assert response.operation.name == "operations/spam" + + +def test_create_index_rest_required_fields( + request_type=firestore_admin.CreateIndexRequest, +): + transport_class = transports.FirestoreAdminRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).create_index._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = "parent_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).create_index._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + + client = FirestoreAdminClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "post", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.create_index(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_create_index_rest_unset_required_fields(): + transport = transports.FirestoreAdminRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.create_index._get_unset_required_fields({}) + assert set(unset_fields) == ( + set(()) + & set( + ( + "parent", + "index", + ) + ) + ) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_create_index_rest_interceptors(null_interceptor): + transport = transports.FirestoreAdminRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.FirestoreAdminRestInterceptor(), + ) + client = FirestoreAdminClient(transport=transport) + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + operation.Operation, "_set_result_from_operation" + ), mock.patch.object( + transports.FirestoreAdminRestInterceptor, "post_create_index" + ) as post, mock.patch.object( + transports.FirestoreAdminRestInterceptor, "pre_create_index" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = firestore_admin.CreateIndexRequest.pb( + firestore_admin.CreateIndexRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = json_format.MessageToJson( + operations_pb2.Operation() + ) + + request = firestore_admin.CreateIndexRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = operations_pb2.Operation() + + client.create_index( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_create_index_rest_bad_request( + transport: str = "rest", request_type=firestore_admin.CreateIndexRequest +): + client = FirestoreAdminClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = { + "parent": "projects/sample1/databases/sample2/collectionGroups/sample3" + } + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.create_index(request) + + +def test_create_index_rest_flattened(): + client = FirestoreAdminClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + + # get arguments that satisfy an http rule for this method + sample_request = { + "parent": "projects/sample1/databases/sample2/collectionGroups/sample3" + } + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + index=gfa_index.Index(name="name_value"), + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.create_index(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{parent=projects/*/databases/*/collectionGroups/*}/indexes" + % client.transport._host, + args[1], + ) + + +def test_create_index_rest_flattened_error(transport: str = "rest"): + client = FirestoreAdminClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.create_index( + firestore_admin.CreateIndexRequest(), + parent="parent_value", + index=gfa_index.Index(name="name_value"), + ) + + +def test_create_index_rest_error(): + client = FirestoreAdminClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + +@pytest.mark.parametrize( + "request_type", + [ + firestore_admin.ListIndexesRequest, + dict, + ], +) +def test_list_indexes_rest(request_type): + client = FirestoreAdminClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = { + "parent": "projects/sample1/databases/sample2/collectionGroups/sample3" + } + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = firestore_admin.ListIndexesResponse( + next_page_token="next_page_token_value", + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = firestore_admin.ListIndexesResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.list_indexes(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListIndexesPager) + assert response.next_page_token == "next_page_token_value" + + +def test_list_indexes_rest_required_fields( + request_type=firestore_admin.ListIndexesRequest, +): + transport_class = transports.FirestoreAdminRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_indexes._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = "parent_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_indexes._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set( + ( + "filter", + "page_size", + "page_token", + ) + ) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + + client = FirestoreAdminClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = firestore_admin.ListIndexesResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = firestore_admin.ListIndexesResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.list_indexes(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_list_indexes_rest_unset_required_fields(): + transport = transports.FirestoreAdminRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.list_indexes._get_unset_required_fields({}) + assert set(unset_fields) == ( + set( + ( + "filter", + "pageSize", + "pageToken", + ) + ) + & set(("parent",)) + ) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_list_indexes_rest_interceptors(null_interceptor): + transport = transports.FirestoreAdminRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.FirestoreAdminRestInterceptor(), + ) + client = FirestoreAdminClient(transport=transport) + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.FirestoreAdminRestInterceptor, "post_list_indexes" + ) as post, mock.patch.object( + transports.FirestoreAdminRestInterceptor, "pre_list_indexes" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = firestore_admin.ListIndexesRequest.pb( + firestore_admin.ListIndexesRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = firestore_admin.ListIndexesResponse.to_json( + firestore_admin.ListIndexesResponse() + ) + + request = firestore_admin.ListIndexesRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = firestore_admin.ListIndexesResponse() + + client.list_indexes( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_list_indexes_rest_bad_request( + transport: str = "rest", request_type=firestore_admin.ListIndexesRequest +): + client = FirestoreAdminClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = { + "parent": "projects/sample1/databases/sample2/collectionGroups/sample3" + } + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.list_indexes(request) + + +def test_list_indexes_rest_flattened(): + client = FirestoreAdminClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = firestore_admin.ListIndexesResponse() + + # get arguments that satisfy an http rule for this method + sample_request = { + "parent": "projects/sample1/databases/sample2/collectionGroups/sample3" + } + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = firestore_admin.ListIndexesResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.list_indexes(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{parent=projects/*/databases/*/collectionGroups/*}/indexes" + % client.transport._host, + args[1], + ) + + +def test_list_indexes_rest_flattened_error(transport: str = "rest"): + client = FirestoreAdminClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_indexes( + firestore_admin.ListIndexesRequest(), + parent="parent_value", + ) + + +def test_list_indexes_rest_pager(transport: str = "rest"): + client = FirestoreAdminClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # TODO(kbandes): remove this mock unless there's a good reason for it. + # with mock.patch.object(path_template, 'transcode') as transcode: + # Set the response as a series of pages + response = ( + firestore_admin.ListIndexesResponse( + indexes=[ + index.Index(), + index.Index(), + index.Index(), + ], + next_page_token="abc", + ), + firestore_admin.ListIndexesResponse( + indexes=[], + next_page_token="def", + ), + firestore_admin.ListIndexesResponse( + indexes=[ + index.Index(), + ], + next_page_token="ghi", + ), + firestore_admin.ListIndexesResponse( + indexes=[ + index.Index(), + index.Index(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple( + firestore_admin.ListIndexesResponse.to_json(x) for x in response + ) + return_values = tuple(Response() for i in response) + for return_val, response_val in zip(return_values, response): + return_val._content = response_val.encode("UTF-8") + return_val.status_code = 200 + req.side_effect = return_values + + sample_request = { + "parent": "projects/sample1/databases/sample2/collectionGroups/sample3" + } + + pager = client.list_indexes(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, index.Index) for i in results) + + pages = list(client.list_indexes(request=sample_request).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +@pytest.mark.parametrize( + "request_type", + [ + firestore_admin.GetIndexRequest, + dict, + ], +) +def test_get_index_rest(request_type): + client = FirestoreAdminClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = { + "name": "projects/sample1/databases/sample2/collectionGroups/sample3/indexes/sample4" + } + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = index.Index( + name="name_value", + query_scope=index.Index.QueryScope.COLLECTION, + api_scope=index.Index.ApiScope.DATASTORE_MODE_API, + state=index.Index.State.CREATING, + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = index.Index.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.get_index(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, index.Index) + assert response.name == "name_value" + assert response.query_scope == index.Index.QueryScope.COLLECTION + assert response.api_scope == index.Index.ApiScope.DATASTORE_MODE_API + assert response.state == index.Index.State.CREATING + + +def test_get_index_rest_required_fields(request_type=firestore_admin.GetIndexRequest): + transport_class = transports.FirestoreAdminRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_index._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = "name_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_index._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" + + client = FirestoreAdminClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = index.Index() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = index.Index.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.get_index(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_get_index_rest_unset_required_fields(): + transport = transports.FirestoreAdminRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.get_index._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name",))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_get_index_rest_interceptors(null_interceptor): + transport = transports.FirestoreAdminRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.FirestoreAdminRestInterceptor(), + ) + client = FirestoreAdminClient(transport=transport) + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.FirestoreAdminRestInterceptor, "post_get_index" + ) as post, mock.patch.object( + transports.FirestoreAdminRestInterceptor, "pre_get_index" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = firestore_admin.GetIndexRequest.pb( + firestore_admin.GetIndexRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = index.Index.to_json(index.Index()) + + request = firestore_admin.GetIndexRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = index.Index() + + client.get_index( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_get_index_rest_bad_request( + transport: str = "rest", request_type=firestore_admin.GetIndexRequest +): + client = FirestoreAdminClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = { + "name": "projects/sample1/databases/sample2/collectionGroups/sample3/indexes/sample4" + } + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.get_index(request) + + +def test_get_index_rest_flattened(): + client = FirestoreAdminClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = index.Index() + + # get arguments that satisfy an http rule for this method + sample_request = { + "name": "projects/sample1/databases/sample2/collectionGroups/sample3/indexes/sample4" + } + + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = index.Index.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.get_index(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{name=projects/*/databases/*/collectionGroups/*/indexes/*}" + % client.transport._host, + args[1], + ) + + +def test_get_index_rest_flattened_error(transport: str = "rest"): + client = FirestoreAdminClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.get_index( + firestore_admin.GetIndexRequest(), + name="name_value", + ) + + +def test_get_index_rest_error(): + client = FirestoreAdminClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + +@pytest.mark.parametrize( + "request_type", + [ + firestore_admin.DeleteIndexRequest, + dict, + ], +) +def test_delete_index_rest(request_type): + client = FirestoreAdminClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = { + "name": "projects/sample1/databases/sample2/collectionGroups/sample3/indexes/sample4" + } + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = None + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = "" + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.delete_index(request) + + # Establish that the response is the type that we expect. + assert response is None + + +def test_delete_index_rest_required_fields( + request_type=firestore_admin.DeleteIndexRequest, +): + transport_class = transports.FirestoreAdminRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).delete_index._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = "name_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).delete_index._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" + + client = FirestoreAdminClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = None + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "delete", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + json_return_value = "" + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.delete_index(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_delete_index_rest_unset_required_fields(): + transport = transports.FirestoreAdminRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.delete_index._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name",))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_delete_index_rest_interceptors(null_interceptor): + transport = transports.FirestoreAdminRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.FirestoreAdminRestInterceptor(), + ) + client = FirestoreAdminClient(transport=transport) + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.FirestoreAdminRestInterceptor, "pre_delete_index" + ) as pre: + pre.assert_not_called() + pb_message = firestore_admin.DeleteIndexRequest.pb( + firestore_admin.DeleteIndexRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + + request = firestore_admin.DeleteIndexRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + + client.delete_index( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + + +def test_delete_index_rest_bad_request( + transport: str = "rest", request_type=firestore_admin.DeleteIndexRequest +): + client = FirestoreAdminClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = { + "name": "projects/sample1/databases/sample2/collectionGroups/sample3/indexes/sample4" + } + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.delete_index(request) + + +def test_delete_index_rest_flattened(): + client = FirestoreAdminClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = None + + # get arguments that satisfy an http rule for this method + sample_request = { + "name": "projects/sample1/databases/sample2/collectionGroups/sample3/indexes/sample4" + } + + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = "" + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.delete_index(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{name=projects/*/databases/*/collectionGroups/*/indexes/*}" + % client.transport._host, + args[1], + ) + + +def test_delete_index_rest_flattened_error(transport: str = "rest"): + client = FirestoreAdminClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.delete_index( + firestore_admin.DeleteIndexRequest(), + name="name_value", + ) + + +def test_delete_index_rest_error(): + client = FirestoreAdminClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + +@pytest.mark.parametrize( + "request_type", + [ + firestore_admin.GetFieldRequest, + dict, + ], +) +def test_get_field_rest(request_type): + client = FirestoreAdminClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = { + "name": "projects/sample1/databases/sample2/collectionGroups/sample3/fields/sample4" + } + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = field.Field( + name="name_value", + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = field.Field.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.get_field(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, field.Field) + assert response.name == "name_value" + + +def test_get_field_rest_required_fields(request_type=firestore_admin.GetFieldRequest): + transport_class = transports.FirestoreAdminRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_field._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = "name_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).get_field._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" + + client = FirestoreAdminClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = field.Field() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = field.Field.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.get_field(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_get_field_rest_unset_required_fields(): + transport = transports.FirestoreAdminRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.get_field._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name",))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_get_field_rest_interceptors(null_interceptor): + transport = transports.FirestoreAdminRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.FirestoreAdminRestInterceptor(), + ) + client = FirestoreAdminClient(transport=transport) + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.FirestoreAdminRestInterceptor, "post_get_field" + ) as post, mock.patch.object( + transports.FirestoreAdminRestInterceptor, "pre_get_field" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = firestore_admin.GetFieldRequest.pb( + firestore_admin.GetFieldRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = field.Field.to_json(field.Field()) + + request = firestore_admin.GetFieldRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = field.Field() + + client.get_field( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_get_field_rest_bad_request( + transport: str = "rest", request_type=firestore_admin.GetFieldRequest +): + client = FirestoreAdminClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = { + "name": "projects/sample1/databases/sample2/collectionGroups/sample3/fields/sample4" + } + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.get_field(request) + + +def test_get_field_rest_flattened(): + client = FirestoreAdminClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = field.Field() + + # get arguments that satisfy an http rule for this method + sample_request = { + "name": "projects/sample1/databases/sample2/collectionGroups/sample3/fields/sample4" + } + + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = field.Field.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.get_field(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{name=projects/*/databases/*/collectionGroups/*/fields/*}" + % client.transport._host, + args[1], + ) + + +def test_get_field_rest_flattened_error(transport: str = "rest"): + client = FirestoreAdminClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.get_field( + firestore_admin.GetFieldRequest(), + name="name_value", + ) + + +def test_get_field_rest_error(): + client = FirestoreAdminClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + +@pytest.mark.parametrize( + "request_type", + [ + firestore_admin.UpdateFieldRequest, + dict, + ], +) +def test_update_field_rest(request_type): + client = FirestoreAdminClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = { + "field": { + "name": "projects/sample1/databases/sample2/collectionGroups/sample3/fields/sample4" + } + } + request_init["field"] = { + "name": "projects/sample1/databases/sample2/collectionGroups/sample3/fields/sample4", + "index_config": { + "indexes": [ + { + "name": "name_value", + "query_scope": 1, + "api_scope": 1, + "fields": [ + { + "field_path": "field_path_value", + "order": 1, + "array_config": 1, + } + ], + "state": 1, + } + ], + "uses_ancestor_config": True, + "ancestor_field": "ancestor_field_value", + "reverting": True, + }, + "ttl_config": {"state": 1}, + } + # The version of a generated dependency at test runtime may differ from the version used during generation. + # Delete any fields which are not present in the current runtime dependency + # See https://github.com/googleapis/gapic-generator-python/issues/1748 + + # Determine if the message type is proto-plus or protobuf + test_field = firestore_admin.UpdateFieldRequest.meta.fields["field"] + + def get_message_fields(field): + # Given a field which is a message (composite type), return a list with + # all the fields of the message. + # If the field is not a composite type, return an empty list. + message_fields = [] + + if hasattr(field, "message") and field.message: + is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + + if is_field_type_proto_plus_type: + message_fields = field.message.meta.fields.values() + # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types + else: # pragma: NO COVER + message_fields = field.message.DESCRIPTOR.fields + return message_fields + + runtime_nested_fields = [ + (field.name, nested_field.name) + for field in get_message_fields(test_field) + for nested_field in get_message_fields(field) + ] + + subfields_not_in_runtime = [] + + # For each item in the sample request, create a list of sub fields which are not present at runtime + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for field, value in request_init["field"].items(): # pragma: NO COVER + result = None + is_repeated = False + # For repeated fields + if isinstance(value, list) and len(value): + is_repeated = True + result = value[0] + # For fields where the type is another message + if isinstance(value, dict): + result = value + + if result and hasattr(result, "keys"): + for subfield in result.keys(): + if (field, subfield) not in runtime_nested_fields: + subfields_not_in_runtime.append( + { + "field": field, + "subfield": subfield, + "is_repeated": is_repeated, + } + ) + + # Remove fields from the sample request which are not present in the runtime version of the dependency + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER + field = subfield_to_delete.get("field") + field_repeated = subfield_to_delete.get("is_repeated") + subfield = subfield_to_delete.get("subfield") + if subfield: + if field_repeated: + for i in range(0, len(request_init["field"][field])): + del request_init["field"][field][i][subfield] + else: + del request_init["field"][field][subfield] + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.update_field(request) + + # Establish that the response is the type that we expect. + assert response.operation.name == "operations/spam" + + +def test_update_field_rest_required_fields( + request_type=firestore_admin.UpdateFieldRequest, +): + transport_class = transports.FirestoreAdminRestTransport + + request_init = {} + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).update_field._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).update_field._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("update_mask",)) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + + client = FirestoreAdminClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "patch", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.update_field(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_update_field_rest_unset_required_fields(): + transport = transports.FirestoreAdminRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.update_field._get_unset_required_fields({}) + assert set(unset_fields) == (set(("updateMask",)) & set(("field",))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_update_field_rest_interceptors(null_interceptor): + transport = transports.FirestoreAdminRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.FirestoreAdminRestInterceptor(), + ) + client = FirestoreAdminClient(transport=transport) + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + operation.Operation, "_set_result_from_operation" + ), mock.patch.object( + transports.FirestoreAdminRestInterceptor, "post_update_field" + ) as post, mock.patch.object( + transports.FirestoreAdminRestInterceptor, "pre_update_field" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = firestore_admin.UpdateFieldRequest.pb( + firestore_admin.UpdateFieldRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = json_format.MessageToJson( + operations_pb2.Operation() + ) + + request = firestore_admin.UpdateFieldRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = operations_pb2.Operation() + + client.update_field( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_update_field_rest_bad_request( + transport: str = "rest", request_type=firestore_admin.UpdateFieldRequest +): + client = FirestoreAdminClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = { + "field": { + "name": "projects/sample1/databases/sample2/collectionGroups/sample3/fields/sample4" + } + } + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.update_field(request) + + +def test_update_field_rest_flattened(): + client = FirestoreAdminClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + + # get arguments that satisfy an http rule for this method + sample_request = { + "field": { + "name": "projects/sample1/databases/sample2/collectionGroups/sample3/fields/sample4" + } + } + + # get truthy value for each flattened field + mock_args = dict( + field=gfa_field.Field(name="name_value"), + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.update_field(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{field.name=projects/*/databases/*/collectionGroups/*/fields/*}" + % client.transport._host, + args[1], + ) + + +def test_update_field_rest_flattened_error(transport: str = "rest"): + client = FirestoreAdminClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.update_field( + firestore_admin.UpdateFieldRequest(), + field=gfa_field.Field(name="name_value"), + ) + + +def test_update_field_rest_error(): + client = FirestoreAdminClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + +@pytest.mark.parametrize( + "request_type", + [ + firestore_admin.ListFieldsRequest, + dict, + ], +) +def test_list_fields_rest(request_type): + client = FirestoreAdminClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = { + "parent": "projects/sample1/databases/sample2/collectionGroups/sample3" + } + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = firestore_admin.ListFieldsResponse( + next_page_token="next_page_token_value", + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = firestore_admin.ListFieldsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.list_fields(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListFieldsPager) + assert response.next_page_token == "next_page_token_value" + + +def test_list_fields_rest_required_fields( + request_type=firestore_admin.ListFieldsRequest, +): + transport_class = transports.FirestoreAdminRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_fields._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = "parent_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).list_fields._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set( + ( + "filter", + "page_size", + "page_token", + ) + ) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + + client = FirestoreAdminClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = firestore_admin.ListFieldsResponse() + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "get", + "query_params": pb_request, + } + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = firestore_admin.ListFieldsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.list_fields(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_list_fields_rest_unset_required_fields(): + transport = transports.FirestoreAdminRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.list_fields._get_unset_required_fields({}) + assert set(unset_fields) == ( + set( + ( + "filter", + "pageSize", + "pageToken", + ) + ) + & set(("parent",)) + ) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_list_fields_rest_interceptors(null_interceptor): + transport = transports.FirestoreAdminRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.FirestoreAdminRestInterceptor(), + ) + client = FirestoreAdminClient(transport=transport) + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + transports.FirestoreAdminRestInterceptor, "post_list_fields" + ) as post, mock.patch.object( + transports.FirestoreAdminRestInterceptor, "pre_list_fields" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = firestore_admin.ListFieldsRequest.pb( + firestore_admin.ListFieldsRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = firestore_admin.ListFieldsResponse.to_json( + firestore_admin.ListFieldsResponse() + ) + + request = firestore_admin.ListFieldsRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = firestore_admin.ListFieldsResponse() + + client.list_fields( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_list_fields_rest_bad_request( + transport: str = "rest", request_type=firestore_admin.ListFieldsRequest +): + client = FirestoreAdminClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = { + "parent": "projects/sample1/databases/sample2/collectionGroups/sample3" + } + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.list_fields(request) + + +def test_list_fields_rest_flattened(): + client = FirestoreAdminClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = firestore_admin.ListFieldsResponse() + + # get arguments that satisfy an http rule for this method + sample_request = { + "parent": "projects/sample1/databases/sample2/collectionGroups/sample3" + } + + # get truthy value for each flattened field + mock_args = dict( + parent="parent_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + # Convert return value to protobuf type + return_value = firestore_admin.ListFieldsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.list_fields(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{parent=projects/*/databases/*/collectionGroups/*}/fields" + % client.transport._host, + args[1], + ) + + +def test_list_fields_rest_flattened_error(transport: str = "rest"): + client = FirestoreAdminClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.list_fields( + firestore_admin.ListFieldsRequest(), + parent="parent_value", + ) + + +def test_list_fields_rest_pager(transport: str = "rest"): + client = FirestoreAdminClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # TODO(kbandes): remove this mock unless there's a good reason for it. + # with mock.patch.object(path_template, 'transcode') as transcode: + # Set the response as a series of pages + response = ( + firestore_admin.ListFieldsResponse( + fields=[ + field.Field(), + field.Field(), + field.Field(), + ], + next_page_token="abc", + ), + firestore_admin.ListFieldsResponse( + fields=[], + next_page_token="def", + ), + firestore_admin.ListFieldsResponse( + fields=[ + field.Field(), + ], + next_page_token="ghi", + ), + firestore_admin.ListFieldsResponse( + fields=[ + field.Field(), + field.Field(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple( + firestore_admin.ListFieldsResponse.to_json(x) for x in response + ) + return_values = tuple(Response() for i in response) + for return_val, response_val in zip(return_values, response): + return_val._content = response_val.encode("UTF-8") + return_val.status_code = 200 + req.side_effect = return_values + + sample_request = { + "parent": "projects/sample1/databases/sample2/collectionGroups/sample3" + } + + pager = client.list_fields(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, field.Field) for i in results) + + pages = list(client.list_fields(request=sample_request).pages) + for page_, token in zip(pages, ["abc", "def", "ghi", ""]): + assert page_.raw_page.next_page_token == token + + +@pytest.mark.parametrize( + "request_type", + [ + firestore_admin.ExportDocumentsRequest, + dict, + ], +) +def test_export_documents_rest(request_type): + client = FirestoreAdminClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {"name": "projects/sample1/databases/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.export_documents(request) + + # Establish that the response is the type that we expect. + assert response.operation.name == "operations/spam" + + +def test_export_documents_rest_required_fields( + request_type=firestore_admin.ExportDocumentsRequest, +): + transport_class = transports.FirestoreAdminRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).export_documents._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = "name_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).export_documents._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" + + client = FirestoreAdminClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "post", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.export_documents(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_export_documents_rest_unset_required_fields(): + transport = transports.FirestoreAdminRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.export_documents._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name",))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_export_documents_rest_interceptors(null_interceptor): + transport = transports.FirestoreAdminRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.FirestoreAdminRestInterceptor(), + ) + client = FirestoreAdminClient(transport=transport) + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + operation.Operation, "_set_result_from_operation" + ), mock.patch.object( + transports.FirestoreAdminRestInterceptor, "post_export_documents" + ) as post, mock.patch.object( + transports.FirestoreAdminRestInterceptor, "pre_export_documents" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = firestore_admin.ExportDocumentsRequest.pb( + firestore_admin.ExportDocumentsRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = json_format.MessageToJson( + operations_pb2.Operation() + ) + + request = firestore_admin.ExportDocumentsRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = operations_pb2.Operation() + + client.export_documents( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_export_documents_rest_bad_request( + transport: str = "rest", request_type=firestore_admin.ExportDocumentsRequest +): + client = FirestoreAdminClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {"name": "projects/sample1/databases/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.export_documents(request) + + +def test_export_documents_rest_flattened(): + client = FirestoreAdminClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + + # get arguments that satisfy an http rule for this method + sample_request = {"name": "projects/sample1/databases/sample2"} + + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.export_documents(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{name=projects/*/databases/*}:exportDocuments" + % client.transport._host, + args[1], + ) + + +def test_export_documents_rest_flattened_error(transport: str = "rest"): + client = FirestoreAdminClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.export_documents( + firestore_admin.ExportDocumentsRequest(), + name="name_value", + ) + + +def test_export_documents_rest_error(): + client = FirestoreAdminClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + +@pytest.mark.parametrize( + "request_type", + [ + firestore_admin.ImportDocumentsRequest, + dict, + ], +) +def test_import_documents_rest(request_type): + client = FirestoreAdminClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {"name": "projects/sample1/databases/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.import_documents(request) + + # Establish that the response is the type that we expect. + assert response.operation.name == "operations/spam" + + +def test_import_documents_rest_required_fields( + request_type=firestore_admin.ImportDocumentsRequest, +): + transport_class = transports.FirestoreAdminRestTransport + + request_init = {} + request_init["name"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson(pb_request, use_integers_for_enums=False) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).import_documents._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["name"] = "name_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).import_documents._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" + + client = FirestoreAdminClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "post", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.import_documents(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_import_documents_rest_unset_required_fields(): + transport = transports.FirestoreAdminRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.import_documents._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name",))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_import_documents_rest_interceptors(null_interceptor): + transport = transports.FirestoreAdminRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None + if null_interceptor + else transports.FirestoreAdminRestInterceptor(), + ) + client = FirestoreAdminClient(transport=transport) + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + operation.Operation, "_set_result_from_operation" + ), mock.patch.object( + transports.FirestoreAdminRestInterceptor, "post_import_documents" + ) as post, mock.patch.object( + transports.FirestoreAdminRestInterceptor, "pre_import_documents" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = firestore_admin.ImportDocumentsRequest.pb( + firestore_admin.ImportDocumentsRequest() + ) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = json_format.MessageToJson( + operations_pb2.Operation() + ) + + request = firestore_admin.ImportDocumentsRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = operations_pb2.Operation() + + client.import_documents( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_import_documents_rest_bad_request( + transport: str = "rest", request_type=firestore_admin.ImportDocumentsRequest +): + client = FirestoreAdminClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {"name": "projects/sample1/databases/sample2"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.import_documents(request) + + +def test_import_documents_rest_flattened(): + client = FirestoreAdminClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + + # get arguments that satisfy an http rule for this method + sample_request = {"name": "projects/sample1/databases/sample2"} + + # get truthy value for each flattened field + mock_args = dict( + name="name_value", + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + client.import_documents(**mock_args) + + # Establish that the underlying call was made with the expected + # request object values. + assert len(req.mock_calls) == 1 + _, args, _ = req.mock_calls[0] + assert path_template.validate( + "%s/v1/{name=projects/*/databases/*}:importDocuments" + % client.transport._host, + args[1], + ) + + +def test_import_documents_rest_flattened_error(transport: str = "rest"): + client = FirestoreAdminClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Attempting to call a method with both a request object and flattened + # fields is an error. + with pytest.raises(ValueError): + client.import_documents( + firestore_admin.ImportDocumentsRequest(), + name="name_value", + ) + + +def test_import_documents_rest_error(): + client = FirestoreAdminClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + +@pytest.mark.parametrize( + "request_type", + [ + firestore_admin.CreateDatabaseRequest, + dict, + ], +) +def test_create_database_rest(request_type): client = FirestoreAdminClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", ) # send a request that will satisfy transcoding - request_init = { - "parent": "projects/sample1/databases/sample2/collectionGroups/sample3" - } - request_init["index"] = { + request_init = {"parent": "projects/sample1"} + request_init["database"] = { "name": "name_value", - "query_scope": 1, - "api_scope": 1, - "fields": [{"field_path": "field_path_value", "order": 1, "array_config": 1}], - "state": 1, + "uid": "uid_value", + "create_time": {"seconds": 751, "nanos": 543}, + "update_time": {}, + "location_id": "location_id_value", + "type_": 1, + "concurrency_mode": 1, + "version_retention_period": {"seconds": 751, "nanos": 543}, + "earliest_version_time": {}, + "point_in_time_recovery_enablement": 1, + "app_engine_integration_mode": 1, + "key_prefix": "key_prefix_value", + "delete_protection_state": 1, + "etag": "etag_value", } # The version of a generated dependency at test runtime may differ from the version used during generation. # Delete any fields which are not present in the current runtime dependency # See https://github.com/googleapis/gapic-generator-python/issues/1748 # Determine if the message type is proto-plus or protobuf - test_field = firestore_admin.CreateIndexRequest.meta.fields["index"] + test_field = firestore_admin.CreateDatabaseRequest.meta.fields["database"] def get_message_fields(field): # Given a field which is a message (composite type), return a list with @@ -4868,7 +9678,7 @@ def get_message_fields(field): # For each item in the sample request, create a list of sub fields which are not present at runtime # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for field, value in request_init["index"].items(): # pragma: NO COVER + for field, value in request_init["database"].items(): # pragma: NO COVER result = None is_repeated = False # For repeated fields @@ -4898,10 +9708,10 @@ def get_message_fields(field): subfield = subfield_to_delete.get("subfield") if subfield: if field_repeated: - for i in range(0, len(request_init["index"][field])): - del request_init["index"][field][i][subfield] + for i in range(0, len(request_init["database"][field])): + del request_init["database"][field][i][subfield] else: - del request_init["index"][field][subfield] + del request_init["database"][field][subfield] request = request_type(**request_init) # Mock the http request call within the method and fake a response. @@ -4916,19 +9726,20 @@ def get_message_fields(field): response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value - response = client.create_index(request) + response = client.create_database(request) # Establish that the response is the type that we expect. assert response.operation.name == "operations/spam" -def test_create_index_rest_required_fields( - request_type=firestore_admin.CreateIndexRequest, +def test_create_database_rest_required_fields( + request_type=firestore_admin.CreateDatabaseRequest, ): transport_class = transports.FirestoreAdminRestTransport request_init = {} request_init["parent"] = "" + request_init["database_id"] = "" request = request_type(**request_init) pb_request = request_type.pb(request) jsonified_request = json.loads( @@ -4936,24 +9747,32 @@ def test_create_index_rest_required_fields( ) # verify fields with default values are dropped + assert "databaseId" not in jsonified_request unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).create_index._get_unset_required_fields(jsonified_request) + ).create_database._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present + assert "databaseId" in jsonified_request + assert jsonified_request["databaseId"] == request_init["database_id"] jsonified_request["parent"] = "parent_value" + jsonified_request["databaseId"] = "database_id_value" unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).create_index._get_unset_required_fields(jsonified_request) + ).create_database._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("database_id",)) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone assert "parent" in jsonified_request assert jsonified_request["parent"] == "parent_value" + assert "databaseId" in jsonified_request + assert jsonified_request["databaseId"] == "database_id_value" client = FirestoreAdminClient( credentials=ga_credentials.AnonymousCredentials(), @@ -4987,32 +9806,39 @@ def test_create_index_rest_required_fields( response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value - response = client.create_index(request) + response = client.create_database(request) - expected_params = [("$alt", "json;enum-encoding=int")] + expected_params = [ + ( + "databaseId", + "", + ), + ("$alt", "json;enum-encoding=int"), + ] actual_params = req.call_args.kwargs["params"] assert expected_params == actual_params -def test_create_index_rest_unset_required_fields(): +def test_create_database_rest_unset_required_fields(): transport = transports.FirestoreAdminRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.create_index._get_unset_required_fields({}) + unset_fields = transport.create_database._get_unset_required_fields({}) assert set(unset_fields) == ( - set(()) + set(("databaseId",)) & set( ( "parent", - "index", + "database", + "databaseId", ) ) ) @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_create_index_rest_interceptors(null_interceptor): +def test_create_database_rest_interceptors(null_interceptor): transport = transports.FirestoreAdminRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -5027,14 +9853,14 @@ def test_create_index_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( operation.Operation, "_set_result_from_operation" ), mock.patch.object( - transports.FirestoreAdminRestInterceptor, "post_create_index" + transports.FirestoreAdminRestInterceptor, "post_create_database" ) as post, mock.patch.object( - transports.FirestoreAdminRestInterceptor, "pre_create_index" + transports.FirestoreAdminRestInterceptor, "pre_create_database" ) as pre: pre.assert_not_called() post.assert_not_called() - pb_message = firestore_admin.CreateIndexRequest.pb( - firestore_admin.CreateIndexRequest() + pb_message = firestore_admin.CreateDatabaseRequest.pb( + firestore_admin.CreateDatabaseRequest() ) transcode.return_value = { "method": "post", @@ -5050,7 +9876,7 @@ def test_create_index_rest_interceptors(null_interceptor): operations_pb2.Operation() ) - request = firestore_admin.CreateIndexRequest() + request = firestore_admin.CreateDatabaseRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), @@ -5058,7 +9884,7 @@ def test_create_index_rest_interceptors(null_interceptor): pre.return_value = request, metadata post.return_value = operations_pb2.Operation() - client.create_index( + client.create_database( request, metadata=[ ("key", "val"), @@ -5070,8 +9896,8 @@ def test_create_index_rest_interceptors(null_interceptor): post.assert_called_once() -def test_create_index_rest_bad_request( - transport: str = "rest", request_type=firestore_admin.CreateIndexRequest +def test_create_database_rest_bad_request( + transport: str = "rest", request_type=firestore_admin.CreateDatabaseRequest ): client = FirestoreAdminClient( credentials=ga_credentials.AnonymousCredentials(), @@ -5079,9 +9905,7 @@ def test_create_index_rest_bad_request( ) # send a request that will satisfy transcoding - request_init = { - "parent": "projects/sample1/databases/sample2/collectionGroups/sample3" - } + request_init = {"parent": "projects/sample1"} request = request_type(**request_init) # Mock the http request call within the method and fake a BadRequest error. @@ -5093,10 +9917,10 @@ def test_create_index_rest_bad_request( response_value.status_code = 400 response_value.request = Request() req.return_value = response_value - client.create_index(request) + client.create_database(request) -def test_create_index_rest_flattened(): +def test_create_database_rest_flattened(): client = FirestoreAdminClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -5108,14 +9932,13 @@ def test_create_index_rest_flattened(): return_value = operations_pb2.Operation(name="operations/spam") # get arguments that satisfy an http rule for this method - sample_request = { - "parent": "projects/sample1/databases/sample2/collectionGroups/sample3" - } + sample_request = {"parent": "projects/sample1"} # get truthy value for each flattened field mock_args = dict( parent="parent_value", - index=gfa_index.Index(name="name_value"), + database=gfa_database.Database(name="name_value"), + database_id="database_id_value", ) mock_args.update(sample_request) @@ -5126,20 +9949,18 @@ def test_create_index_rest_flattened(): response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value - client.create_index(**mock_args) + client.create_database(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1/{parent=projects/*/databases/*/collectionGroups/*}/indexes" - % client.transport._host, - args[1], + "%s/v1/{parent=projects/*}/databases" % client.transport._host, args[1] ) -def test_create_index_rest_flattened_error(transport: str = "rest"): +def test_create_database_rest_flattened_error(transport: str = "rest"): client = FirestoreAdminClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -5148,14 +9969,15 @@ def test_create_index_rest_flattened_error(transport: str = "rest"): # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.create_index( - firestore_admin.CreateIndexRequest(), + client.create_database( + firestore_admin.CreateDatabaseRequest(), parent="parent_value", - index=gfa_index.Index(name="name_value"), + database=gfa_database.Database(name="name_value"), + database_id="database_id_value", ) -def test_create_index_rest_error(): +def test_create_database_rest_error(): client = FirestoreAdminClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) @@ -5164,52 +9986,77 @@ def test_create_index_rest_error(): @pytest.mark.parametrize( "request_type", [ - firestore_admin.ListIndexesRequest, + firestore_admin.GetDatabaseRequest, dict, ], ) -def test_list_indexes_rest(request_type): +def test_get_database_rest(request_type): client = FirestoreAdminClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", ) # send a request that will satisfy transcoding - request_init = { - "parent": "projects/sample1/databases/sample2/collectionGroups/sample3" - } + request_init = {"name": "projects/sample1/databases/sample2"} request = request_type(**request_init) # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = firestore_admin.ListIndexesResponse( - next_page_token="next_page_token_value", + return_value = database.Database( + name="name_value", + uid="uid_value", + location_id="location_id_value", + type_=database.Database.DatabaseType.FIRESTORE_NATIVE, + concurrency_mode=database.Database.ConcurrencyMode.OPTIMISTIC, + point_in_time_recovery_enablement=database.Database.PointInTimeRecoveryEnablement.POINT_IN_TIME_RECOVERY_ENABLED, + app_engine_integration_mode=database.Database.AppEngineIntegrationMode.ENABLED, + key_prefix="key_prefix_value", + delete_protection_state=database.Database.DeleteProtectionState.DELETE_PROTECTION_DISABLED, + etag="etag_value", ) # Wrap the value into a proper Response obj response_value = Response() response_value.status_code = 200 # Convert return value to protobuf type - return_value = firestore_admin.ListIndexesResponse.pb(return_value) + return_value = database.Database.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value - response = client.list_indexes(request) + response = client.get_database(request) # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListIndexesPager) - assert response.next_page_token == "next_page_token_value" + assert isinstance(response, database.Database) + assert response.name == "name_value" + assert response.uid == "uid_value" + assert response.location_id == "location_id_value" + assert response.type_ == database.Database.DatabaseType.FIRESTORE_NATIVE + assert response.concurrency_mode == database.Database.ConcurrencyMode.OPTIMISTIC + assert ( + response.point_in_time_recovery_enablement + == database.Database.PointInTimeRecoveryEnablement.POINT_IN_TIME_RECOVERY_ENABLED + ) + assert ( + response.app_engine_integration_mode + == database.Database.AppEngineIntegrationMode.ENABLED + ) + assert response.key_prefix == "key_prefix_value" + assert ( + response.delete_protection_state + == database.Database.DeleteProtectionState.DELETE_PROTECTION_DISABLED + ) + assert response.etag == "etag_value" -def test_list_indexes_rest_required_fields( - request_type=firestore_admin.ListIndexesRequest, +def test_get_database_rest_required_fields( + request_type=firestore_admin.GetDatabaseRequest, ): transport_class = transports.FirestoreAdminRestTransport request_init = {} - request_init["parent"] = "" + request_init["name"] = "" request = request_type(**request_init) pb_request = request_type.pb(request) jsonified_request = json.loads( @@ -5220,29 +10067,21 @@ def test_list_indexes_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).list_indexes._get_unset_required_fields(jsonified_request) + ).get_database._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present - jsonified_request["parent"] = "parent_value" + jsonified_request["name"] = "name_value" unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).list_indexes._get_unset_required_fields(jsonified_request) - # Check that path parameters and body parameters are not mixing in. - assert not set(unset_fields) - set( - ( - "filter", - "page_size", - "page_token", - ) - ) + ).get_database._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone - assert "parent" in jsonified_request - assert jsonified_request["parent"] == "parent_value" + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" client = FirestoreAdminClient( credentials=ga_credentials.AnonymousCredentials(), @@ -5251,7 +10090,7 @@ def test_list_indexes_rest_required_fields( request = request_type(**request_init) # Designate an appropriate value for the returned response. - return_value = firestore_admin.ListIndexesResponse() + return_value = database.Database() # Mock the http request call within the method and fake a response. with mock.patch.object(Session, "request") as req: # We need to mock transcode() because providing default values @@ -5272,39 +10111,30 @@ def test_list_indexes_rest_required_fields( response_value.status_code = 200 # Convert return value to protobuf type - return_value = firestore_admin.ListIndexesResponse.pb(return_value) + return_value = database.Database.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value - response = client.list_indexes(request) + response = client.get_database(request) expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] assert expected_params == actual_params -def test_list_indexes_rest_unset_required_fields(): +def test_get_database_rest_unset_required_fields(): transport = transports.FirestoreAdminRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.list_indexes._get_unset_required_fields({}) - assert set(unset_fields) == ( - set( - ( - "filter", - "pageSize", - "pageToken", - ) - ) - & set(("parent",)) - ) + unset_fields = transport.get_database._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name",))) @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_list_indexes_rest_interceptors(null_interceptor): +def test_get_database_rest_interceptors(null_interceptor): transport = transports.FirestoreAdminRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -5317,14 +10147,14 @@ def test_list_indexes_rest_interceptors(null_interceptor): ) as req, mock.patch.object( path_template, "transcode" ) as transcode, mock.patch.object( - transports.FirestoreAdminRestInterceptor, "post_list_indexes" + transports.FirestoreAdminRestInterceptor, "post_get_database" ) as post, mock.patch.object( - transports.FirestoreAdminRestInterceptor, "pre_list_indexes" + transports.FirestoreAdminRestInterceptor, "pre_get_database" ) as pre: pre.assert_not_called() post.assert_not_called() - pb_message = firestore_admin.ListIndexesRequest.pb( - firestore_admin.ListIndexesRequest() + pb_message = firestore_admin.GetDatabaseRequest.pb( + firestore_admin.GetDatabaseRequest() ) transcode.return_value = { "method": "post", @@ -5336,19 +10166,17 @@ def test_list_indexes_rest_interceptors(null_interceptor): req.return_value = Response() req.return_value.status_code = 200 req.return_value.request = PreparedRequest() - req.return_value._content = firestore_admin.ListIndexesResponse.to_json( - firestore_admin.ListIndexesResponse() - ) + req.return_value._content = database.Database.to_json(database.Database()) - request = firestore_admin.ListIndexesRequest() + request = firestore_admin.GetDatabaseRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = firestore_admin.ListIndexesResponse() + post.return_value = database.Database() - client.list_indexes( + client.get_database( request, metadata=[ ("key", "val"), @@ -5360,8 +10188,8 @@ def test_list_indexes_rest_interceptors(null_interceptor): post.assert_called_once() -def test_list_indexes_rest_bad_request( - transport: str = "rest", request_type=firestore_admin.ListIndexesRequest +def test_get_database_rest_bad_request( + transport: str = "rest", request_type=firestore_admin.GetDatabaseRequest ): client = FirestoreAdminClient( credentials=ga_credentials.AnonymousCredentials(), @@ -5369,9 +10197,7 @@ def test_list_indexes_rest_bad_request( ) # send a request that will satisfy transcoding - request_init = { - "parent": "projects/sample1/databases/sample2/collectionGroups/sample3" - } + request_init = {"name": "projects/sample1/databases/sample2"} request = request_type(**request_init) # Mock the http request call within the method and fake a BadRequest error. @@ -5383,10 +10209,10 @@ def test_list_indexes_rest_bad_request( response_value.status_code = 400 response_value.request = Request() req.return_value = response_value - client.list_indexes(request) + client.get_database(request) -def test_list_indexes_rest_flattened(): +def test_get_database_rest_flattened(): client = FirestoreAdminClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -5395,16 +10221,14 @@ def test_list_indexes_rest_flattened(): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = firestore_admin.ListIndexesResponse() + return_value = database.Database() # get arguments that satisfy an http rule for this method - sample_request = { - "parent": "projects/sample1/databases/sample2/collectionGroups/sample3" - } + sample_request = {"name": "projects/sample1/databases/sample2"} # get truthy value for each flattened field mock_args = dict( - parent="parent_value", + name="name_value", ) mock_args.update(sample_request) @@ -5412,25 +10236,23 @@ def test_list_indexes_rest_flattened(): response_value = Response() response_value.status_code = 200 # Convert return value to protobuf type - return_value = firestore_admin.ListIndexesResponse.pb(return_value) + return_value = database.Database.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value - client.list_indexes(**mock_args) + client.get_database(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1/{parent=projects/*/databases/*/collectionGroups/*}/indexes" - % client.transport._host, - args[1], + "%s/v1/{name=projects/*/databases/*}" % client.transport._host, args[1] ) -def test_list_indexes_rest_flattened_error(transport: str = "rest"): +def test_get_database_rest_flattened_error(transport: str = "rest"): client = FirestoreAdminClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -5439,130 +10261,65 @@ def test_list_indexes_rest_flattened_error(transport: str = "rest"): # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.list_indexes( - firestore_admin.ListIndexesRequest(), - parent="parent_value", - ) - - -def test_list_indexes_rest_pager(transport: str = "rest"): - client = FirestoreAdminClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # TODO(kbandes): remove this mock unless there's a good reason for it. - # with mock.patch.object(path_template, 'transcode') as transcode: - # Set the response as a series of pages - response = ( - firestore_admin.ListIndexesResponse( - indexes=[ - index.Index(), - index.Index(), - index.Index(), - ], - next_page_token="abc", - ), - firestore_admin.ListIndexesResponse( - indexes=[], - next_page_token="def", - ), - firestore_admin.ListIndexesResponse( - indexes=[ - index.Index(), - ], - next_page_token="ghi", - ), - firestore_admin.ListIndexesResponse( - indexes=[ - index.Index(), - index.Index(), - ], - ), - ) - # Two responses for two calls - response = response + response - - # Wrap the values into proper Response objs - response = tuple( - firestore_admin.ListIndexesResponse.to_json(x) for x in response + client.get_database( + firestore_admin.GetDatabaseRequest(), + name="name_value", ) - return_values = tuple(Response() for i in response) - for return_val, response_val in zip(return_values, response): - return_val._content = response_val.encode("UTF-8") - return_val.status_code = 200 - req.side_effect = return_values - - sample_request = { - "parent": "projects/sample1/databases/sample2/collectionGroups/sample3" - } - - pager = client.list_indexes(request=sample_request) - results = list(pager) - assert len(results) == 6 - assert all(isinstance(i, index.Index) for i in results) - pages = list(client.list_indexes(request=sample_request).pages) - for page_, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page_.raw_page.next_page_token == token +def test_get_database_rest_error(): + client = FirestoreAdminClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) @pytest.mark.parametrize( "request_type", [ - firestore_admin.GetIndexRequest, + firestore_admin.ListDatabasesRequest, dict, ], ) -def test_get_index_rest(request_type): +def test_list_databases_rest(request_type): client = FirestoreAdminClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", ) # send a request that will satisfy transcoding - request_init = { - "name": "projects/sample1/databases/sample2/collectionGroups/sample3/indexes/sample4" - } + request_init = {"parent": "projects/sample1"} request = request_type(**request_init) # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = index.Index( - name="name_value", - query_scope=index.Index.QueryScope.COLLECTION, - api_scope=index.Index.ApiScope.DATASTORE_MODE_API, - state=index.Index.State.CREATING, + return_value = firestore_admin.ListDatabasesResponse( + unreachable=["unreachable_value"], ) # Wrap the value into a proper Response obj response_value = Response() response_value.status_code = 200 # Convert return value to protobuf type - return_value = index.Index.pb(return_value) + return_value = firestore_admin.ListDatabasesResponse.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value - response = client.get_index(request) + response = client.list_databases(request) # Establish that the response is the type that we expect. - assert isinstance(response, index.Index) - assert response.name == "name_value" - assert response.query_scope == index.Index.QueryScope.COLLECTION - assert response.api_scope == index.Index.ApiScope.DATASTORE_MODE_API - assert response.state == index.Index.State.CREATING + assert isinstance(response, firestore_admin.ListDatabasesResponse) + assert response.unreachable == ["unreachable_value"] -def test_get_index_rest_required_fields(request_type=firestore_admin.GetIndexRequest): +def test_list_databases_rest_required_fields( + request_type=firestore_admin.ListDatabasesRequest, +): transport_class = transports.FirestoreAdminRestTransport request_init = {} - request_init["name"] = "" + request_init["parent"] = "" request = request_type(**request_init) pb_request = request_type.pb(request) jsonified_request = json.loads( @@ -5573,21 +10330,21 @@ def test_get_index_rest_required_fields(request_type=firestore_admin.GetIndexReq unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).get_index._get_unset_required_fields(jsonified_request) + ).list_databases._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present - jsonified_request["name"] = "name_value" + jsonified_request["parent"] = "parent_value" unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).get_index._get_unset_required_fields(jsonified_request) + ).list_databases._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone - assert "name" in jsonified_request - assert jsonified_request["name"] == "name_value" + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" client = FirestoreAdminClient( credentials=ga_credentials.AnonymousCredentials(), @@ -5596,7 +10353,7 @@ def test_get_index_rest_required_fields(request_type=firestore_admin.GetIndexReq request = request_type(**request_init) # Designate an appropriate value for the returned response. - return_value = index.Index() + return_value = firestore_admin.ListDatabasesResponse() # Mock the http request call within the method and fake a response. with mock.patch.object(Session, "request") as req: # We need to mock transcode() because providing default values @@ -5617,30 +10374,30 @@ def test_get_index_rest_required_fields(request_type=firestore_admin.GetIndexReq response_value.status_code = 200 # Convert return value to protobuf type - return_value = index.Index.pb(return_value) + return_value = firestore_admin.ListDatabasesResponse.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value - response = client.get_index(request) + response = client.list_databases(request) expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] assert expected_params == actual_params -def test_get_index_rest_unset_required_fields(): +def test_list_databases_rest_unset_required_fields(): transport = transports.FirestoreAdminRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.get_index._get_unset_required_fields({}) - assert set(unset_fields) == (set(()) & set(("name",))) + unset_fields = transport.list_databases._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("parent",))) @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_get_index_rest_interceptors(null_interceptor): +def test_list_databases_rest_interceptors(null_interceptor): transport = transports.FirestoreAdminRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -5653,14 +10410,14 @@ def test_get_index_rest_interceptors(null_interceptor): ) as req, mock.patch.object( path_template, "transcode" ) as transcode, mock.patch.object( - transports.FirestoreAdminRestInterceptor, "post_get_index" + transports.FirestoreAdminRestInterceptor, "post_list_databases" ) as post, mock.patch.object( - transports.FirestoreAdminRestInterceptor, "pre_get_index" + transports.FirestoreAdminRestInterceptor, "pre_list_databases" ) as pre: pre.assert_not_called() post.assert_not_called() - pb_message = firestore_admin.GetIndexRequest.pb( - firestore_admin.GetIndexRequest() + pb_message = firestore_admin.ListDatabasesRequest.pb( + firestore_admin.ListDatabasesRequest() ) transcode.return_value = { "method": "post", @@ -5672,17 +10429,19 @@ def test_get_index_rest_interceptors(null_interceptor): req.return_value = Response() req.return_value.status_code = 200 req.return_value.request = PreparedRequest() - req.return_value._content = index.Index.to_json(index.Index()) + req.return_value._content = firestore_admin.ListDatabasesResponse.to_json( + firestore_admin.ListDatabasesResponse() + ) - request = firestore_admin.GetIndexRequest() + request = firestore_admin.ListDatabasesRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = index.Index() + post.return_value = firestore_admin.ListDatabasesResponse() - client.get_index( + client.list_databases( request, metadata=[ ("key", "val"), @@ -5694,8 +10453,8 @@ def test_get_index_rest_interceptors(null_interceptor): post.assert_called_once() -def test_get_index_rest_bad_request( - transport: str = "rest", request_type=firestore_admin.GetIndexRequest +def test_list_databases_rest_bad_request( + transport: str = "rest", request_type=firestore_admin.ListDatabasesRequest ): client = FirestoreAdminClient( credentials=ga_credentials.AnonymousCredentials(), @@ -5703,9 +10462,7 @@ def test_get_index_rest_bad_request( ) # send a request that will satisfy transcoding - request_init = { - "name": "projects/sample1/databases/sample2/collectionGroups/sample3/indexes/sample4" - } + request_init = {"parent": "projects/sample1"} request = request_type(**request_init) # Mock the http request call within the method and fake a BadRequest error. @@ -5717,10 +10474,10 @@ def test_get_index_rest_bad_request( response_value.status_code = 400 response_value.request = Request() req.return_value = response_value - client.get_index(request) + client.list_databases(request) -def test_get_index_rest_flattened(): +def test_list_databases_rest_flattened(): client = FirestoreAdminClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -5729,16 +10486,14 @@ def test_get_index_rest_flattened(): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = index.Index() + return_value = firestore_admin.ListDatabasesResponse() # get arguments that satisfy an http rule for this method - sample_request = { - "name": "projects/sample1/databases/sample2/collectionGroups/sample3/indexes/sample4" - } + sample_request = {"parent": "projects/sample1"} # get truthy value for each flattened field mock_args = dict( - name="name_value", + parent="parent_value", ) mock_args.update(sample_request) @@ -5746,25 +10501,23 @@ def test_get_index_rest_flattened(): response_value = Response() response_value.status_code = 200 # Convert return value to protobuf type - return_value = index.Index.pb(return_value) + return_value = firestore_admin.ListDatabasesResponse.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value - client.get_index(**mock_args) + client.list_databases(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1/{name=projects/*/databases/*/collectionGroups/*/indexes/*}" - % client.transport._host, - args[1], + "%s/v1/{parent=projects/*}/databases" % client.transport._host, args[1] ) -def test_get_index_rest_flattened_error(transport: str = "rest"): +def test_list_databases_rest_flattened_error(transport: str = "rest"): client = FirestoreAdminClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -5773,13 +10526,13 @@ def test_get_index_rest_flattened_error(transport: str = "rest"): # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.get_index( - firestore_admin.GetIndexRequest(), - name="name_value", + client.list_databases( + firestore_admin.ListDatabasesRequest(), + parent="parent_value", ) -def test_get_index_rest_error(): +def test_list_databases_rest_error(): client = FirestoreAdminClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) @@ -5788,47 +10541,127 @@ def test_get_index_rest_error(): @pytest.mark.parametrize( "request_type", [ - firestore_admin.DeleteIndexRequest, + firestore_admin.UpdateDatabaseRequest, dict, ], ) -def test_delete_index_rest(request_type): +def test_update_database_rest(request_type): client = FirestoreAdminClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", ) # send a request that will satisfy transcoding - request_init = { - "name": "projects/sample1/databases/sample2/collectionGroups/sample3/indexes/sample4" + request_init = {"database": {"name": "projects/sample1/databases/sample2"}} + request_init["database"] = { + "name": "projects/sample1/databases/sample2", + "uid": "uid_value", + "create_time": {"seconds": 751, "nanos": 543}, + "update_time": {}, + "location_id": "location_id_value", + "type_": 1, + "concurrency_mode": 1, + "version_retention_period": {"seconds": 751, "nanos": 543}, + "earliest_version_time": {}, + "point_in_time_recovery_enablement": 1, + "app_engine_integration_mode": 1, + "key_prefix": "key_prefix_value", + "delete_protection_state": 1, + "etag": "etag_value", } + # The version of a generated dependency at test runtime may differ from the version used during generation. + # Delete any fields which are not present in the current runtime dependency + # See https://github.com/googleapis/gapic-generator-python/issues/1748 + + # Determine if the message type is proto-plus or protobuf + test_field = firestore_admin.UpdateDatabaseRequest.meta.fields["database"] + + def get_message_fields(field): + # Given a field which is a message (composite type), return a list with + # all the fields of the message. + # If the field is not a composite type, return an empty list. + message_fields = [] + + if hasattr(field, "message") and field.message: + is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") + + if is_field_type_proto_plus_type: + message_fields = field.message.meta.fields.values() + # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types + else: # pragma: NO COVER + message_fields = field.message.DESCRIPTOR.fields + return message_fields + + runtime_nested_fields = [ + (field.name, nested_field.name) + for field in get_message_fields(test_field) + for nested_field in get_message_fields(field) + ] + + subfields_not_in_runtime = [] + + # For each item in the sample request, create a list of sub fields which are not present at runtime + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for field, value in request_init["database"].items(): # pragma: NO COVER + result = None + is_repeated = False + # For repeated fields + if isinstance(value, list) and len(value): + is_repeated = True + result = value[0] + # For fields where the type is another message + if isinstance(value, dict): + result = value + + if result and hasattr(result, "keys"): + for subfield in result.keys(): + if (field, subfield) not in runtime_nested_fields: + subfields_not_in_runtime.append( + { + "field": field, + "subfield": subfield, + "is_repeated": is_repeated, + } + ) + + # Remove fields from the sample request which are not present in the runtime version of the dependency + # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime + for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER + field = subfield_to_delete.get("field") + field_repeated = subfield_to_delete.get("is_repeated") + subfield = subfield_to_delete.get("subfield") + if subfield: + if field_repeated: + for i in range(0, len(request_init["database"][field])): + del request_init["database"][field][i][subfield] + else: + del request_init["database"][field][subfield] request = request_type(**request_init) # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = None + return_value = operations_pb2.Operation(name="operations/spam") # Wrap the value into a proper Response obj response_value = Response() response_value.status_code = 200 - json_return_value = "" + json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value - response = client.delete_index(request) + response = client.update_database(request) # Establish that the response is the type that we expect. - assert response is None + assert response.operation.name == "operations/spam" -def test_delete_index_rest_required_fields( - request_type=firestore_admin.DeleteIndexRequest, +def test_update_database_rest_required_fields( + request_type=firestore_admin.UpdateDatabaseRequest, ): transport_class = transports.FirestoreAdminRestTransport request_init = {} - request_init["name"] = "" request = request_type(**request_init) pb_request = request_type.pb(request) jsonified_request = json.loads( @@ -5839,21 +10672,19 @@ def test_delete_index_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).delete_index._get_unset_required_fields(jsonified_request) + ).update_database._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present - jsonified_request["name"] = "name_value" - unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).delete_index._get_unset_required_fields(jsonified_request) + ).update_database._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("update_mask",)) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone - assert "name" in jsonified_request - assert jsonified_request["name"] == "name_value" client = FirestoreAdminClient( credentials=ga_credentials.AnonymousCredentials(), @@ -5862,7 +10693,7 @@ def test_delete_index_rest_required_fields( request = request_type(**request_init) # Designate an appropriate value for the returned response. - return_value = None + return_value = operations_pb2.Operation(name="operations/spam") # Mock the http request call within the method and fake a response. with mock.patch.object(Session, "request") as req: # We need to mock transcode() because providing default values @@ -5874,36 +10705,37 @@ def test_delete_index_rest_required_fields( pb_request = request_type.pb(request) transcode_result = { "uri": "v1/sample_method", - "method": "delete", + "method": "patch", "query_params": pb_request, } + transcode_result["body"] = pb_request transcode.return_value = transcode_result response_value = Response() response_value.status_code = 200 - json_return_value = "" + json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value - response = client.delete_index(request) + response = client.update_database(request) expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] assert expected_params == actual_params -def test_delete_index_rest_unset_required_fields(): +def test_update_database_rest_unset_required_fields(): transport = transports.FirestoreAdminRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.delete_index._get_unset_required_fields({}) - assert set(unset_fields) == (set(()) & set(("name",))) + unset_fields = transport.update_database._get_unset_required_fields({}) + assert set(unset_fields) == (set(("updateMask",)) & set(("database",))) @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_delete_index_rest_interceptors(null_interceptor): +def test_update_database_rest_interceptors(null_interceptor): transport = transports.FirestoreAdminRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -5916,11 +10748,16 @@ def test_delete_index_rest_interceptors(null_interceptor): ) as req, mock.patch.object( path_template, "transcode" ) as transcode, mock.patch.object( - transports.FirestoreAdminRestInterceptor, "pre_delete_index" + operation.Operation, "_set_result_from_operation" + ), mock.patch.object( + transports.FirestoreAdminRestInterceptor, "post_update_database" + ) as post, mock.patch.object( + transports.FirestoreAdminRestInterceptor, "pre_update_database" ) as pre: pre.assert_not_called() - pb_message = firestore_admin.DeleteIndexRequest.pb( - firestore_admin.DeleteIndexRequest() + post.assert_not_called() + pb_message = firestore_admin.UpdateDatabaseRequest.pb( + firestore_admin.UpdateDatabaseRequest() ) transcode.return_value = { "method": "post", @@ -5932,15 +10769,19 @@ def test_delete_index_rest_interceptors(null_interceptor): req.return_value = Response() req.return_value.status_code = 200 req.return_value.request = PreparedRequest() + req.return_value._content = json_format.MessageToJson( + operations_pb2.Operation() + ) - request = firestore_admin.DeleteIndexRequest() + request = firestore_admin.UpdateDatabaseRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata + post.return_value = operations_pb2.Operation() - client.delete_index( + client.update_database( request, metadata=[ ("key", "val"), @@ -5949,10 +10790,11 @@ def test_delete_index_rest_interceptors(null_interceptor): ) pre.assert_called_once() + post.assert_called_once() -def test_delete_index_rest_bad_request( - transport: str = "rest", request_type=firestore_admin.DeleteIndexRequest +def test_update_database_rest_bad_request( + transport: str = "rest", request_type=firestore_admin.UpdateDatabaseRequest ): client = FirestoreAdminClient( credentials=ga_credentials.AnonymousCredentials(), @@ -5960,9 +10802,7 @@ def test_delete_index_rest_bad_request( ) # send a request that will satisfy transcoding - request_init = { - "name": "projects/sample1/databases/sample2/collectionGroups/sample3/indexes/sample4" - } + request_init = {"database": {"name": "projects/sample1/databases/sample2"}} request = request_type(**request_init) # Mock the http request call within the method and fake a BadRequest error. @@ -5974,10 +10814,10 @@ def test_delete_index_rest_bad_request( response_value.status_code = 400 response_value.request = Request() req.return_value = response_value - client.delete_index(request) + client.update_database(request) -def test_delete_index_rest_flattened(): +def test_update_database_rest_flattened(): client = FirestoreAdminClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -5986,40 +10826,38 @@ def test_delete_index_rest_flattened(): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = None + return_value = operations_pb2.Operation(name="operations/spam") # get arguments that satisfy an http rule for this method - sample_request = { - "name": "projects/sample1/databases/sample2/collectionGroups/sample3/indexes/sample4" - } + sample_request = {"database": {"name": "projects/sample1/databases/sample2"}} # get truthy value for each flattened field mock_args = dict( - name="name_value", + database=gfa_database.Database(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), ) mock_args.update(sample_request) # Wrap the value into a proper Response obj response_value = Response() response_value.status_code = 200 - json_return_value = "" + json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value - client.delete_index(**mock_args) + client.update_database(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1/{name=projects/*/databases/*/collectionGroups/*/indexes/*}" - % client.transport._host, + "%s/v1/{database.name=projects/*/databases/*}" % client.transport._host, args[1], ) -def test_delete_index_rest_flattened_error(transport: str = "rest"): +def test_update_database_rest_flattened_error(transport: str = "rest"): client = FirestoreAdminClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -6028,13 +10866,14 @@ def test_delete_index_rest_flattened_error(transport: str = "rest"): # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.delete_index( - firestore_admin.DeleteIndexRequest(), - name="name_value", + client.update_database( + firestore_admin.UpdateDatabaseRequest(), + database=gfa_database.Database(name="name_value"), + update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), ) -def test_delete_index_rest_error(): +def test_update_database_rest_error(): client = FirestoreAdminClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) @@ -6043,46 +10882,41 @@ def test_delete_index_rest_error(): @pytest.mark.parametrize( "request_type", [ - firestore_admin.GetFieldRequest, + firestore_admin.DeleteDatabaseRequest, dict, ], ) -def test_get_field_rest(request_type): +def test_delete_database_rest(request_type): client = FirestoreAdminClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", ) # send a request that will satisfy transcoding - request_init = { - "name": "projects/sample1/databases/sample2/collectionGroups/sample3/fields/sample4" - } + request_init = {"name": "projects/sample1/databases/sample2"} request = request_type(**request_init) # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = field.Field( - name="name_value", - ) + return_value = operations_pb2.Operation(name="operations/spam") # Wrap the value into a proper Response obj response_value = Response() response_value.status_code = 200 - # Convert return value to protobuf type - return_value = field.Field.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value - response = client.get_field(request) + response = client.delete_database(request) # Establish that the response is the type that we expect. - assert isinstance(response, field.Field) - assert response.name == "name_value" + assert response.operation.name == "operations/spam" -def test_get_field_rest_required_fields(request_type=firestore_admin.GetFieldRequest): +def test_delete_database_rest_required_fields( + request_type=firestore_admin.DeleteDatabaseRequest, +): transport_class = transports.FirestoreAdminRestTransport request_init = {} @@ -6097,7 +10931,7 @@ def test_get_field_rest_required_fields(request_type=firestore_admin.GetFieldReq unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).get_field._get_unset_required_fields(jsonified_request) + ).delete_database._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present @@ -6106,7 +10940,9 @@ def test_get_field_rest_required_fields(request_type=firestore_admin.GetFieldReq unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).get_field._get_unset_required_fields(jsonified_request) + ).delete_database._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("etag",)) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone @@ -6120,7 +10956,7 @@ def test_get_field_rest_required_fields(request_type=firestore_admin.GetFieldReq request = request_type(**request_init) # Designate an appropriate value for the returned response. - return_value = field.Field() + return_value = operations_pb2.Operation(name="operations/spam") # Mock the http request call within the method and fake a response. with mock.patch.object(Session, "request") as req: # We need to mock transcode() because providing default values @@ -6132,39 +10968,36 @@ def test_get_field_rest_required_fields(request_type=firestore_admin.GetFieldReq pb_request = request_type.pb(request) transcode_result = { "uri": "v1/sample_method", - "method": "get", + "method": "delete", "query_params": pb_request, } transcode.return_value = transcode_result response_value = Response() response_value.status_code = 200 - - # Convert return value to protobuf type - return_value = field.Field.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value - response = client.get_field(request) + response = client.delete_database(request) expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] assert expected_params == actual_params -def test_get_field_rest_unset_required_fields(): +def test_delete_database_rest_unset_required_fields(): transport = transports.FirestoreAdminRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.get_field._get_unset_required_fields({}) - assert set(unset_fields) == (set(()) & set(("name",))) + unset_fields = transport.delete_database._get_unset_required_fields({}) + assert set(unset_fields) == (set(("etag",)) & set(("name",))) @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_get_field_rest_interceptors(null_interceptor): +def test_delete_database_rest_interceptors(null_interceptor): transport = transports.FirestoreAdminRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -6177,14 +11010,16 @@ def test_get_field_rest_interceptors(null_interceptor): ) as req, mock.patch.object( path_template, "transcode" ) as transcode, mock.patch.object( - transports.FirestoreAdminRestInterceptor, "post_get_field" + operation.Operation, "_set_result_from_operation" + ), mock.patch.object( + transports.FirestoreAdminRestInterceptor, "post_delete_database" ) as post, mock.patch.object( - transports.FirestoreAdminRestInterceptor, "pre_get_field" + transports.FirestoreAdminRestInterceptor, "pre_delete_database" ) as pre: pre.assert_not_called() post.assert_not_called() - pb_message = firestore_admin.GetFieldRequest.pb( - firestore_admin.GetFieldRequest() + pb_message = firestore_admin.DeleteDatabaseRequest.pb( + firestore_admin.DeleteDatabaseRequest() ) transcode.return_value = { "method": "post", @@ -6196,17 +11031,19 @@ def test_get_field_rest_interceptors(null_interceptor): req.return_value = Response() req.return_value.status_code = 200 req.return_value.request = PreparedRequest() - req.return_value._content = field.Field.to_json(field.Field()) + req.return_value._content = json_format.MessageToJson( + operations_pb2.Operation() + ) - request = firestore_admin.GetFieldRequest() + request = firestore_admin.DeleteDatabaseRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = field.Field() + post.return_value = operations_pb2.Operation() - client.get_field( + client.delete_database( request, metadata=[ ("key", "val"), @@ -6218,8 +11055,8 @@ def test_get_field_rest_interceptors(null_interceptor): post.assert_called_once() -def test_get_field_rest_bad_request( - transport: str = "rest", request_type=firestore_admin.GetFieldRequest +def test_delete_database_rest_bad_request( + transport: str = "rest", request_type=firestore_admin.DeleteDatabaseRequest ): client = FirestoreAdminClient( credentials=ga_credentials.AnonymousCredentials(), @@ -6227,9 +11064,7 @@ def test_get_field_rest_bad_request( ) # send a request that will satisfy transcoding - request_init = { - "name": "projects/sample1/databases/sample2/collectionGroups/sample3/fields/sample4" - } + request_init = {"name": "projects/sample1/databases/sample2"} request = request_type(**request_init) # Mock the http request call within the method and fake a BadRequest error. @@ -6241,10 +11076,10 @@ def test_get_field_rest_bad_request( response_value.status_code = 400 response_value.request = Request() req.return_value = response_value - client.get_field(request) + client.delete_database(request) -def test_get_field_rest_flattened(): +def test_delete_database_rest_flattened(): client = FirestoreAdminClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -6253,12 +11088,10 @@ def test_get_field_rest_flattened(): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = field.Field() + return_value = operations_pb2.Operation(name="operations/spam") # get arguments that satisfy an http rule for this method - sample_request = { - "name": "projects/sample1/databases/sample2/collectionGroups/sample3/fields/sample4" - } + sample_request = {"name": "projects/sample1/databases/sample2"} # get truthy value for each flattened field mock_args = dict( @@ -6269,26 +11102,22 @@ def test_get_field_rest_flattened(): # Wrap the value into a proper Response obj response_value = Response() response_value.status_code = 200 - # Convert return value to protobuf type - return_value = field.Field.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value - client.get_field(**mock_args) + client.delete_database(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1/{name=projects/*/databases/*/collectionGroups/*/fields/*}" - % client.transport._host, - args[1], + "%s/v1/{name=projects/*/databases/*}" % client.transport._host, args[1] ) -def test_get_field_rest_flattened_error(transport: str = "rest"): +def test_delete_database_rest_flattened_error(transport: str = "rest"): client = FirestoreAdminClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -6297,13 +11126,13 @@ def test_get_field_rest_flattened_error(transport: str = "rest"): # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.get_field( - firestore_admin.GetFieldRequest(), + client.delete_database( + firestore_admin.DeleteDatabaseRequest(), name="name_value", ) -def test_get_field_rest_error(): +def test_delete_database_rest_error(): client = FirestoreAdminClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) @@ -6312,139 +11141,54 @@ def test_get_field_rest_error(): @pytest.mark.parametrize( "request_type", [ - firestore_admin.UpdateFieldRequest, + firestore_admin.GetBackupRequest, dict, ], ) -def test_update_field_rest(request_type): +def test_get_backup_rest(request_type): client = FirestoreAdminClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", ) # send a request that will satisfy transcoding - request_init = { - "field": { - "name": "projects/sample1/databases/sample2/collectionGroups/sample3/fields/sample4" - } - } - request_init["field"] = { - "name": "projects/sample1/databases/sample2/collectionGroups/sample3/fields/sample4", - "index_config": { - "indexes": [ - { - "name": "name_value", - "query_scope": 1, - "api_scope": 1, - "fields": [ - { - "field_path": "field_path_value", - "order": 1, - "array_config": 1, - } - ], - "state": 1, - } - ], - "uses_ancestor_config": True, - "ancestor_field": "ancestor_field_value", - "reverting": True, - }, - "ttl_config": {"state": 1}, - } - # The version of a generated dependency at test runtime may differ from the version used during generation. - # Delete any fields which are not present in the current runtime dependency - # See https://github.com/googleapis/gapic-generator-python/issues/1748 - - # Determine if the message type is proto-plus or protobuf - test_field = firestore_admin.UpdateFieldRequest.meta.fields["field"] - - def get_message_fields(field): - # Given a field which is a message (composite type), return a list with - # all the fields of the message. - # If the field is not a composite type, return an empty list. - message_fields = [] - - if hasattr(field, "message") and field.message: - is_field_type_proto_plus_type = not hasattr(field.message, "DESCRIPTOR") - - if is_field_type_proto_plus_type: - message_fields = field.message.meta.fields.values() - # Add `# pragma: NO COVER` because there may not be any `*_pb2` field types - else: # pragma: NO COVER - message_fields = field.message.DESCRIPTOR.fields - return message_fields - - runtime_nested_fields = [ - (field.name, nested_field.name) - for field in get_message_fields(test_field) - for nested_field in get_message_fields(field) - ] - - subfields_not_in_runtime = [] - - # For each item in the sample request, create a list of sub fields which are not present at runtime - # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for field, value in request_init["field"].items(): # pragma: NO COVER - result = None - is_repeated = False - # For repeated fields - if isinstance(value, list) and len(value): - is_repeated = True - result = value[0] - # For fields where the type is another message - if isinstance(value, dict): - result = value - - if result and hasattr(result, "keys"): - for subfield in result.keys(): - if (field, subfield) not in runtime_nested_fields: - subfields_not_in_runtime.append( - { - "field": field, - "subfield": subfield, - "is_repeated": is_repeated, - } - ) - - # Remove fields from the sample request which are not present in the runtime version of the dependency - # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for subfield_to_delete in subfields_not_in_runtime: # pragma: NO COVER - field = subfield_to_delete.get("field") - field_repeated = subfield_to_delete.get("is_repeated") - subfield = subfield_to_delete.get("subfield") - if subfield: - if field_repeated: - for i in range(0, len(request_init["field"][field])): - del request_init["field"][field][i][subfield] - else: - del request_init["field"][field][subfield] + request_init = {"name": "projects/sample1/locations/sample2/backups/sample3"} request = request_type(**request_init) # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") + return_value = backup.Backup( + name="name_value", + database="database_value", + database_uid="database_uid_value", + state=backup.Backup.State.CREATING, + ) # Wrap the value into a proper Response obj response_value = Response() response_value.status_code = 200 + # Convert return value to protobuf type + return_value = backup.Backup.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value - response = client.update_field(request) + response = client.get_backup(request) # Establish that the response is the type that we expect. - assert response.operation.name == "operations/spam" + assert isinstance(response, backup.Backup) + assert response.name == "name_value" + assert response.database == "database_value" + assert response.database_uid == "database_uid_value" + assert response.state == backup.Backup.State.CREATING -def test_update_field_rest_required_fields( - request_type=firestore_admin.UpdateFieldRequest, -): +def test_get_backup_rest_required_fields(request_type=firestore_admin.GetBackupRequest): transport_class = transports.FirestoreAdminRestTransport request_init = {} + request_init["name"] = "" request = request_type(**request_init) pb_request = request_type.pb(request) jsonified_request = json.loads( @@ -6455,19 +11199,21 @@ def test_update_field_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).update_field._get_unset_required_fields(jsonified_request) + ).get_backup._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present + jsonified_request["name"] = "name_value" + unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).update_field._get_unset_required_fields(jsonified_request) - # Check that path parameters and body parameters are not mixing in. - assert not set(unset_fields) - set(("update_mask",)) + ).get_backup._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone + assert "name" in jsonified_request + assert jsonified_request["name"] == "name_value" client = FirestoreAdminClient( credentials=ga_credentials.AnonymousCredentials(), @@ -6476,7 +11222,7 @@ def test_update_field_rest_required_fields( request = request_type(**request_init) # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") + return_value = backup.Backup() # Mock the http request call within the method and fake a response. with mock.patch.object(Session, "request") as req: # We need to mock transcode() because providing default values @@ -6488,37 +11234,39 @@ def test_update_field_rest_required_fields( pb_request = request_type.pb(request) transcode_result = { "uri": "v1/sample_method", - "method": "patch", + "method": "get", "query_params": pb_request, } - transcode_result["body"] = pb_request transcode.return_value = transcode_result response_value = Response() response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = backup.Backup.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value - response = client.update_field(request) + response = client.get_backup(request) expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] assert expected_params == actual_params -def test_update_field_rest_unset_required_fields(): +def test_get_backup_rest_unset_required_fields(): transport = transports.FirestoreAdminRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.update_field._get_unset_required_fields({}) - assert set(unset_fields) == (set(("updateMask",)) & set(("field",))) + unset_fields = transport.get_backup._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name",))) @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_update_field_rest_interceptors(null_interceptor): +def test_get_backup_rest_interceptors(null_interceptor): transport = transports.FirestoreAdminRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -6531,16 +11279,14 @@ def test_update_field_rest_interceptors(null_interceptor): ) as req, mock.patch.object( path_template, "transcode" ) as transcode, mock.patch.object( - operation.Operation, "_set_result_from_operation" - ), mock.patch.object( - transports.FirestoreAdminRestInterceptor, "post_update_field" + transports.FirestoreAdminRestInterceptor, "post_get_backup" ) as post, mock.patch.object( - transports.FirestoreAdminRestInterceptor, "pre_update_field" + transports.FirestoreAdminRestInterceptor, "pre_get_backup" ) as pre: pre.assert_not_called() post.assert_not_called() - pb_message = firestore_admin.UpdateFieldRequest.pb( - firestore_admin.UpdateFieldRequest() + pb_message = firestore_admin.GetBackupRequest.pb( + firestore_admin.GetBackupRequest() ) transcode.return_value = { "method": "post", @@ -6552,19 +11298,17 @@ def test_update_field_rest_interceptors(null_interceptor): req.return_value = Response() req.return_value.status_code = 200 req.return_value.request = PreparedRequest() - req.return_value._content = json_format.MessageToJson( - operations_pb2.Operation() - ) + req.return_value._content = backup.Backup.to_json(backup.Backup()) - request = firestore_admin.UpdateFieldRequest() + request = firestore_admin.GetBackupRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = operations_pb2.Operation() + post.return_value = backup.Backup() - client.update_field( + client.get_backup( request, metadata=[ ("key", "val"), @@ -6576,8 +11320,8 @@ def test_update_field_rest_interceptors(null_interceptor): post.assert_called_once() -def test_update_field_rest_bad_request( - transport: str = "rest", request_type=firestore_admin.UpdateFieldRequest +def test_get_backup_rest_bad_request( + transport: str = "rest", request_type=firestore_admin.GetBackupRequest ): client = FirestoreAdminClient( credentials=ga_credentials.AnonymousCredentials(), @@ -6585,11 +11329,7 @@ def test_update_field_rest_bad_request( ) # send a request that will satisfy transcoding - request_init = { - "field": { - "name": "projects/sample1/databases/sample2/collectionGroups/sample3/fields/sample4" - } - } + request_init = {"name": "projects/sample1/locations/sample2/backups/sample3"} request = request_type(**request_init) # Mock the http request call within the method and fake a BadRequest error. @@ -6601,10 +11341,10 @@ def test_update_field_rest_bad_request( response_value.status_code = 400 response_value.request = Request() req.return_value = response_value - client.update_field(request) + client.get_backup(request) -def test_update_field_rest_flattened(): +def test_get_backup_rest_flattened(): client = FirestoreAdminClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -6613,42 +11353,39 @@ def test_update_field_rest_flattened(): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") + return_value = backup.Backup() # get arguments that satisfy an http rule for this method - sample_request = { - "field": { - "name": "projects/sample1/databases/sample2/collectionGroups/sample3/fields/sample4" - } - } + sample_request = {"name": "projects/sample1/locations/sample2/backups/sample3"} # get truthy value for each flattened field mock_args = dict( - field=gfa_field.Field(name="name_value"), + name="name_value", ) mock_args.update(sample_request) # Wrap the value into a proper Response obj response_value = Response() response_value.status_code = 200 + # Convert return value to protobuf type + return_value = backup.Backup.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value - client.update_field(**mock_args) + client.get_backup(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1/{field.name=projects/*/databases/*/collectionGroups/*/fields/*}" - % client.transport._host, + "%s/v1/{name=projects/*/locations/*/backups/*}" % client.transport._host, args[1], ) -def test_update_field_rest_flattened_error(transport: str = "rest"): +def test_get_backup_rest_flattened_error(transport: str = "rest"): client = FirestoreAdminClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -6657,13 +11394,13 @@ def test_update_field_rest_flattened_error(transport: str = "rest"): # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.update_field( - firestore_admin.UpdateFieldRequest(), - field=gfa_field.Field(name="name_value"), + client.get_backup( + firestore_admin.GetBackupRequest(), + name="name_value", ) -def test_update_field_rest_error(): +def test_get_backup_rest_error(): client = FirestoreAdminClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) @@ -6672,47 +11409,45 @@ def test_update_field_rest_error(): @pytest.mark.parametrize( "request_type", [ - firestore_admin.ListFieldsRequest, + firestore_admin.ListBackupsRequest, dict, ], ) -def test_list_fields_rest(request_type): +def test_list_backups_rest(request_type): client = FirestoreAdminClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", ) # send a request that will satisfy transcoding - request_init = { - "parent": "projects/sample1/databases/sample2/collectionGroups/sample3" - } + request_init = {"parent": "projects/sample1/locations/sample2"} request = request_type(**request_init) # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = firestore_admin.ListFieldsResponse( - next_page_token="next_page_token_value", + return_value = firestore_admin.ListBackupsResponse( + unreachable=["unreachable_value"], ) # Wrap the value into a proper Response obj response_value = Response() response_value.status_code = 200 # Convert return value to protobuf type - return_value = firestore_admin.ListFieldsResponse.pb(return_value) + return_value = firestore_admin.ListBackupsResponse.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value - response = client.list_fields(request) + response = client.list_backups(request) # Establish that the response is the type that we expect. - assert isinstance(response, pagers.ListFieldsPager) - assert response.next_page_token == "next_page_token_value" + assert isinstance(response, firestore_admin.ListBackupsResponse) + assert response.unreachable == ["unreachable_value"] -def test_list_fields_rest_required_fields( - request_type=firestore_admin.ListFieldsRequest, +def test_list_backups_rest_required_fields( + request_type=firestore_admin.ListBackupsRequest, ): transport_class = transports.FirestoreAdminRestTransport @@ -6728,7 +11463,7 @@ def test_list_fields_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).list_fields._get_unset_required_fields(jsonified_request) + ).list_backups._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present @@ -6737,15 +11472,7 @@ def test_list_fields_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).list_fields._get_unset_required_fields(jsonified_request) - # Check that path parameters and body parameters are not mixing in. - assert not set(unset_fields) - set( - ( - "filter", - "page_size", - "page_token", - ) - ) + ).list_backups._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone @@ -6759,7 +11486,7 @@ def test_list_fields_rest_required_fields( request = request_type(**request_init) # Designate an appropriate value for the returned response. - return_value = firestore_admin.ListFieldsResponse() + return_value = firestore_admin.ListBackupsResponse() # Mock the http request call within the method and fake a response. with mock.patch.object(Session, "request") as req: # We need to mock transcode() because providing default values @@ -6780,39 +11507,30 @@ def test_list_fields_rest_required_fields( response_value.status_code = 200 # Convert return value to protobuf type - return_value = firestore_admin.ListFieldsResponse.pb(return_value) + return_value = firestore_admin.ListBackupsResponse.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value - response = client.list_fields(request) + response = client.list_backups(request) expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] assert expected_params == actual_params -def test_list_fields_rest_unset_required_fields(): +def test_list_backups_rest_unset_required_fields(): transport = transports.FirestoreAdminRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.list_fields._get_unset_required_fields({}) - assert set(unset_fields) == ( - set( - ( - "filter", - "pageSize", - "pageToken", - ) - ) - & set(("parent",)) - ) + unset_fields = transport.list_backups._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("parent",))) @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_list_fields_rest_interceptors(null_interceptor): +def test_list_backups_rest_interceptors(null_interceptor): transport = transports.FirestoreAdminRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -6825,14 +11543,14 @@ def test_list_fields_rest_interceptors(null_interceptor): ) as req, mock.patch.object( path_template, "transcode" ) as transcode, mock.patch.object( - transports.FirestoreAdminRestInterceptor, "post_list_fields" + transports.FirestoreAdminRestInterceptor, "post_list_backups" ) as post, mock.patch.object( - transports.FirestoreAdminRestInterceptor, "pre_list_fields" + transports.FirestoreAdminRestInterceptor, "pre_list_backups" ) as pre: pre.assert_not_called() post.assert_not_called() - pb_message = firestore_admin.ListFieldsRequest.pb( - firestore_admin.ListFieldsRequest() + pb_message = firestore_admin.ListBackupsRequest.pb( + firestore_admin.ListBackupsRequest() ) transcode.return_value = { "method": "post", @@ -6844,19 +11562,19 @@ def test_list_fields_rest_interceptors(null_interceptor): req.return_value = Response() req.return_value.status_code = 200 req.return_value.request = PreparedRequest() - req.return_value._content = firestore_admin.ListFieldsResponse.to_json( - firestore_admin.ListFieldsResponse() + req.return_value._content = firestore_admin.ListBackupsResponse.to_json( + firestore_admin.ListBackupsResponse() ) - request = firestore_admin.ListFieldsRequest() + request = firestore_admin.ListBackupsRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = firestore_admin.ListFieldsResponse() + post.return_value = firestore_admin.ListBackupsResponse() - client.list_fields( + client.list_backups( request, metadata=[ ("key", "val"), @@ -6868,8 +11586,8 @@ def test_list_fields_rest_interceptors(null_interceptor): post.assert_called_once() -def test_list_fields_rest_bad_request( - transport: str = "rest", request_type=firestore_admin.ListFieldsRequest +def test_list_backups_rest_bad_request( + transport: str = "rest", request_type=firestore_admin.ListBackupsRequest ): client = FirestoreAdminClient( credentials=ga_credentials.AnonymousCredentials(), @@ -6877,9 +11595,7 @@ def test_list_fields_rest_bad_request( ) # send a request that will satisfy transcoding - request_init = { - "parent": "projects/sample1/databases/sample2/collectionGroups/sample3" - } + request_init = {"parent": "projects/sample1/locations/sample2"} request = request_type(**request_init) # Mock the http request call within the method and fake a BadRequest error. @@ -6891,10 +11607,10 @@ def test_list_fields_rest_bad_request( response_value.status_code = 400 response_value.request = Request() req.return_value = response_value - client.list_fields(request) + client.list_backups(request) -def test_list_fields_rest_flattened(): +def test_list_backups_rest_flattened(): client = FirestoreAdminClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -6903,12 +11619,10 @@ def test_list_fields_rest_flattened(): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = firestore_admin.ListFieldsResponse() + return_value = firestore_admin.ListBackupsResponse() # get arguments that satisfy an http rule for this method - sample_request = { - "parent": "projects/sample1/databases/sample2/collectionGroups/sample3" - } + sample_request = {"parent": "projects/sample1/locations/sample2"} # get truthy value for each flattened field mock_args = dict( @@ -6920,25 +11634,24 @@ def test_list_fields_rest_flattened(): response_value = Response() response_value.status_code = 200 # Convert return value to protobuf type - return_value = firestore_admin.ListFieldsResponse.pb(return_value) + return_value = firestore_admin.ListBackupsResponse.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value - client.list_fields(**mock_args) + client.list_backups(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1/{parent=projects/*/databases/*/collectionGroups/*}/fields" - % client.transport._host, + "%s/v1/{parent=projects/*/locations/*}/backups" % client.transport._host, args[1], ) -def test_list_fields_rest_flattened_error(transport: str = "rest"): +def test_list_backups_rest_flattened_error(transport: str = "rest"): client = FirestoreAdminClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -6947,114 +11660,55 @@ def test_list_fields_rest_flattened_error(transport: str = "rest"): # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.list_fields( - firestore_admin.ListFieldsRequest(), + client.list_backups( + firestore_admin.ListBackupsRequest(), parent="parent_value", ) -def test_list_fields_rest_pager(transport: str = "rest"): +def test_list_backups_rest_error(): client = FirestoreAdminClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, + credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) - # Mock the http request call within the method and fake a response. - with mock.patch.object(Session, "request") as req: - # TODO(kbandes): remove this mock unless there's a good reason for it. - # with mock.patch.object(path_template, 'transcode') as transcode: - # Set the response as a series of pages - response = ( - firestore_admin.ListFieldsResponse( - fields=[ - field.Field(), - field.Field(), - field.Field(), - ], - next_page_token="abc", - ), - firestore_admin.ListFieldsResponse( - fields=[], - next_page_token="def", - ), - firestore_admin.ListFieldsResponse( - fields=[ - field.Field(), - ], - next_page_token="ghi", - ), - firestore_admin.ListFieldsResponse( - fields=[ - field.Field(), - field.Field(), - ], - ), - ) - # Two responses for two calls - response = response + response - - # Wrap the values into proper Response objs - response = tuple( - firestore_admin.ListFieldsResponse.to_json(x) for x in response - ) - return_values = tuple(Response() for i in response) - for return_val, response_val in zip(return_values, response): - return_val._content = response_val.encode("UTF-8") - return_val.status_code = 200 - req.side_effect = return_values - - sample_request = { - "parent": "projects/sample1/databases/sample2/collectionGroups/sample3" - } - - pager = client.list_fields(request=sample_request) - - results = list(pager) - assert len(results) == 6 - assert all(isinstance(i, field.Field) for i in results) - - pages = list(client.list_fields(request=sample_request).pages) - for page_, token in zip(pages, ["abc", "def", "ghi", ""]): - assert page_.raw_page.next_page_token == token - @pytest.mark.parametrize( "request_type", [ - firestore_admin.ExportDocumentsRequest, + firestore_admin.DeleteBackupRequest, dict, ], ) -def test_export_documents_rest(request_type): +def test_delete_backup_rest(request_type): client = FirestoreAdminClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", ) # send a request that will satisfy transcoding - request_init = {"name": "projects/sample1/databases/sample2"} + request_init = {"name": "projects/sample1/locations/sample2/backups/sample3"} request = request_type(**request_init) # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") + return_value = None # Wrap the value into a proper Response obj response_value = Response() response_value.status_code = 200 - json_return_value = json_format.MessageToJson(return_value) + json_return_value = "" response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value - response = client.export_documents(request) + response = client.delete_backup(request) # Establish that the response is the type that we expect. - assert response.operation.name == "operations/spam" + assert response is None -def test_export_documents_rest_required_fields( - request_type=firestore_admin.ExportDocumentsRequest, +def test_delete_backup_rest_required_fields( + request_type=firestore_admin.DeleteBackupRequest, ): transport_class = transports.FirestoreAdminRestTransport @@ -7070,7 +11724,7 @@ def test_export_documents_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).export_documents._get_unset_required_fields(jsonified_request) + ).delete_backup._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present @@ -7079,7 +11733,7 @@ def test_export_documents_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).export_documents._get_unset_required_fields(jsonified_request) + ).delete_backup._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone @@ -7093,7 +11747,7 @@ def test_export_documents_rest_required_fields( request = request_type(**request_init) # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") + return_value = None # Mock the http request call within the method and fake a response. with mock.patch.object(Session, "request") as req: # We need to mock transcode() because providing default values @@ -7105,37 +11759,36 @@ def test_export_documents_rest_required_fields( pb_request = request_type.pb(request) transcode_result = { "uri": "v1/sample_method", - "method": "post", + "method": "delete", "query_params": pb_request, } - transcode_result["body"] = pb_request transcode.return_value = transcode_result response_value = Response() response_value.status_code = 200 - json_return_value = json_format.MessageToJson(return_value) + json_return_value = "" response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value - response = client.export_documents(request) + response = client.delete_backup(request) expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] assert expected_params == actual_params -def test_export_documents_rest_unset_required_fields(): +def test_delete_backup_rest_unset_required_fields(): transport = transports.FirestoreAdminRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.export_documents._get_unset_required_fields({}) + unset_fields = transport.delete_backup._get_unset_required_fields({}) assert set(unset_fields) == (set(()) & set(("name",))) @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_export_documents_rest_interceptors(null_interceptor): +def test_delete_backup_rest_interceptors(null_interceptor): transport = transports.FirestoreAdminRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -7148,16 +11801,11 @@ def test_export_documents_rest_interceptors(null_interceptor): ) as req, mock.patch.object( path_template, "transcode" ) as transcode, mock.patch.object( - operation.Operation, "_set_result_from_operation" - ), mock.patch.object( - transports.FirestoreAdminRestInterceptor, "post_export_documents" - ) as post, mock.patch.object( - transports.FirestoreAdminRestInterceptor, "pre_export_documents" + transports.FirestoreAdminRestInterceptor, "pre_delete_backup" ) as pre: pre.assert_not_called() - post.assert_not_called() - pb_message = firestore_admin.ExportDocumentsRequest.pb( - firestore_admin.ExportDocumentsRequest() + pb_message = firestore_admin.DeleteBackupRequest.pb( + firestore_admin.DeleteBackupRequest() ) transcode.return_value = { "method": "post", @@ -7169,19 +11817,15 @@ def test_export_documents_rest_interceptors(null_interceptor): req.return_value = Response() req.return_value.status_code = 200 req.return_value.request = PreparedRequest() - req.return_value._content = json_format.MessageToJson( - operations_pb2.Operation() - ) - request = firestore_admin.ExportDocumentsRequest() + request = firestore_admin.DeleteBackupRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = operations_pb2.Operation() - client.export_documents( + client.delete_backup( request, metadata=[ ("key", "val"), @@ -7190,11 +11834,10 @@ def test_export_documents_rest_interceptors(null_interceptor): ) pre.assert_called_once() - post.assert_called_once() -def test_export_documents_rest_bad_request( - transport: str = "rest", request_type=firestore_admin.ExportDocumentsRequest +def test_delete_backup_rest_bad_request( + transport: str = "rest", request_type=firestore_admin.DeleteBackupRequest ): client = FirestoreAdminClient( credentials=ga_credentials.AnonymousCredentials(), @@ -7202,7 +11845,7 @@ def test_export_documents_rest_bad_request( ) # send a request that will satisfy transcoding - request_init = {"name": "projects/sample1/databases/sample2"} + request_init = {"name": "projects/sample1/locations/sample2/backups/sample3"} request = request_type(**request_init) # Mock the http request call within the method and fake a BadRequest error. @@ -7214,10 +11857,10 @@ def test_export_documents_rest_bad_request( response_value.status_code = 400 response_value.request = Request() req.return_value = response_value - client.export_documents(request) + client.delete_backup(request) -def test_export_documents_rest_flattened(): +def test_delete_backup_rest_flattened(): client = FirestoreAdminClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -7226,10 +11869,10 @@ def test_export_documents_rest_flattened(): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") + return_value = None # get arguments that satisfy an http rule for this method - sample_request = {"name": "projects/sample1/databases/sample2"} + sample_request = {"name": "projects/sample1/locations/sample2/backups/sample3"} # get truthy value for each flattened field mock_args = dict( @@ -7240,24 +11883,23 @@ def test_export_documents_rest_flattened(): # Wrap the value into a proper Response obj response_value = Response() response_value.status_code = 200 - json_return_value = json_format.MessageToJson(return_value) + json_return_value = "" response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value - client.export_documents(**mock_args) + client.delete_backup(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1/{name=projects/*/databases/*}:exportDocuments" - % client.transport._host, + "%s/v1/{name=projects/*/locations/*/backups/*}" % client.transport._host, args[1], ) -def test_export_documents_rest_flattened_error(transport: str = "rest"): +def test_delete_backup_rest_flattened_error(transport: str = "rest"): client = FirestoreAdminClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -7266,13 +11908,13 @@ def test_export_documents_rest_flattened_error(transport: str = "rest"): # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.export_documents( - firestore_admin.ExportDocumentsRequest(), + client.delete_backup( + firestore_admin.DeleteBackupRequest(), name="name_value", ) -def test_export_documents_rest_error(): +def test_delete_backup_rest_error(): client = FirestoreAdminClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) @@ -7281,18 +11923,18 @@ def test_export_documents_rest_error(): @pytest.mark.parametrize( "request_type", [ - firestore_admin.ImportDocumentsRequest, + firestore_admin.RestoreDatabaseRequest, dict, ], ) -def test_import_documents_rest(request_type): +def test_restore_database_rest(request_type): client = FirestoreAdminClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", ) # send a request that will satisfy transcoding - request_init = {"name": "projects/sample1/databases/sample2"} + request_init = {"parent": "projects/sample1"} request = request_type(**request_init) # Mock the http request call within the method and fake a response. @@ -7307,19 +11949,21 @@ def test_import_documents_rest(request_type): response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value - response = client.import_documents(request) + response = client.restore_database(request) # Establish that the response is the type that we expect. assert response.operation.name == "operations/spam" -def test_import_documents_rest_required_fields( - request_type=firestore_admin.ImportDocumentsRequest, +def test_restore_database_rest_required_fields( + request_type=firestore_admin.RestoreDatabaseRequest, ): transport_class = transports.FirestoreAdminRestTransport request_init = {} - request_init["name"] = "" + request_init["parent"] = "" + request_init["database_id"] = "" + request_init["backup"] = "" request = request_type(**request_init) pb_request = request_type.pb(request) jsonified_request = json.loads( @@ -7330,21 +11974,27 @@ def test_import_documents_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).import_documents._get_unset_required_fields(jsonified_request) + ).restore_database._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present - jsonified_request["name"] = "name_value" + jsonified_request["parent"] = "parent_value" + jsonified_request["databaseId"] = "database_id_value" + jsonified_request["backup"] = "backup_value" unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).import_documents._get_unset_required_fields(jsonified_request) + ).restore_database._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone - assert "name" in jsonified_request - assert jsonified_request["name"] == "name_value" + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + assert "databaseId" in jsonified_request + assert jsonified_request["databaseId"] == "database_id_value" + assert "backup" in jsonified_request + assert jsonified_request["backup"] == "backup_value" client = FirestoreAdminClient( credentials=ga_credentials.AnonymousCredentials(), @@ -7378,24 +12028,33 @@ def test_import_documents_rest_required_fields( response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value - response = client.import_documents(request) + response = client.restore_database(request) expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] assert expected_params == actual_params -def test_import_documents_rest_unset_required_fields(): +def test_restore_database_rest_unset_required_fields(): transport = transports.FirestoreAdminRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.import_documents._get_unset_required_fields({}) - assert set(unset_fields) == (set(()) & set(("name",))) + unset_fields = transport.restore_database._get_unset_required_fields({}) + assert set(unset_fields) == ( + set(()) + & set( + ( + "parent", + "databaseId", + "backup", + ) + ) + ) @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_import_documents_rest_interceptors(null_interceptor): +def test_restore_database_rest_interceptors(null_interceptor): transport = transports.FirestoreAdminRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -7410,14 +12069,14 @@ def test_import_documents_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( operation.Operation, "_set_result_from_operation" ), mock.patch.object( - transports.FirestoreAdminRestInterceptor, "post_import_documents" + transports.FirestoreAdminRestInterceptor, "post_restore_database" ) as post, mock.patch.object( - transports.FirestoreAdminRestInterceptor, "pre_import_documents" + transports.FirestoreAdminRestInterceptor, "pre_restore_database" ) as pre: pre.assert_not_called() post.assert_not_called() - pb_message = firestore_admin.ImportDocumentsRequest.pb( - firestore_admin.ImportDocumentsRequest() + pb_message = firestore_admin.RestoreDatabaseRequest.pb( + firestore_admin.RestoreDatabaseRequest() ) transcode.return_value = { "method": "post", @@ -7433,7 +12092,7 @@ def test_import_documents_rest_interceptors(null_interceptor): operations_pb2.Operation() ) - request = firestore_admin.ImportDocumentsRequest() + request = firestore_admin.RestoreDatabaseRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), @@ -7441,7 +12100,7 @@ def test_import_documents_rest_interceptors(null_interceptor): pre.return_value = request, metadata post.return_value = operations_pb2.Operation() - client.import_documents( + client.restore_database( request, metadata=[ ("key", "val"), @@ -7453,8 +12112,8 @@ def test_import_documents_rest_interceptors(null_interceptor): post.assert_called_once() -def test_import_documents_rest_bad_request( - transport: str = "rest", request_type=firestore_admin.ImportDocumentsRequest +def test_restore_database_rest_bad_request( + transport: str = "rest", request_type=firestore_admin.RestoreDatabaseRequest ): client = FirestoreAdminClient( credentials=ga_credentials.AnonymousCredentials(), @@ -7462,7 +12121,7 @@ def test_import_documents_rest_bad_request( ) # send a request that will satisfy transcoding - request_init = {"name": "projects/sample1/databases/sample2"} + request_init = {"parent": "projects/sample1"} request = request_type(**request_init) # Mock the http request call within the method and fake a BadRequest error. @@ -7474,65 +12133,10 @@ def test_import_documents_rest_bad_request( response_value.status_code = 400 response_value.request = Request() req.return_value = response_value - client.import_documents(request) - - -def test_import_documents_rest_flattened(): - client = FirestoreAdminClient( - credentials=ga_credentials.AnonymousCredentials(), - transport="rest", - ) - - # Mock the http request call within the method and fake a response. - with mock.patch.object(type(client.transport._session), "request") as req: - # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") - - # get arguments that satisfy an http rule for this method - sample_request = {"name": "projects/sample1/databases/sample2"} - - # get truthy value for each flattened field - mock_args = dict( - name="name_value", - ) - mock_args.update(sample_request) - - # Wrap the value into a proper Response obj - response_value = Response() - response_value.status_code = 200 - json_return_value = json_format.MessageToJson(return_value) - response_value._content = json_return_value.encode("UTF-8") - req.return_value = response_value - - client.import_documents(**mock_args) - - # Establish that the underlying call was made with the expected - # request object values. - assert len(req.mock_calls) == 1 - _, args, _ = req.mock_calls[0] - assert path_template.validate( - "%s/v1/{name=projects/*/databases/*}:importDocuments" - % client.transport._host, - args[1], - ) - - -def test_import_documents_rest_flattened_error(transport: str = "rest"): - client = FirestoreAdminClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # Attempting to call a method with both a request object and flattened - # fields is an error. - with pytest.raises(ValueError): - client.import_documents( - firestore_admin.ImportDocumentsRequest(), - name="name_value", - ) + client.restore_database(request) -def test_import_documents_rest_error(): +def test_restore_database_rest_error(): client = FirestoreAdminClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) @@ -7541,40 +12145,34 @@ def test_import_documents_rest_error(): @pytest.mark.parametrize( "request_type", [ - firestore_admin.CreateDatabaseRequest, + firestore_admin.CreateBackupScheduleRequest, dict, ], ) -def test_create_database_rest(request_type): +def test_create_backup_schedule_rest(request_type): client = FirestoreAdminClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", ) # send a request that will satisfy transcoding - request_init = {"parent": "projects/sample1"} - request_init["database"] = { + request_init = {"parent": "projects/sample1/databases/sample2"} + request_init["backup_schedule"] = { "name": "name_value", - "uid": "uid_value", "create_time": {"seconds": 751, "nanos": 543}, "update_time": {}, - "location_id": "location_id_value", - "type_": 1, - "concurrency_mode": 1, - "version_retention_period": {"seconds": 751, "nanos": 543}, - "earliest_version_time": {}, - "point_in_time_recovery_enablement": 1, - "app_engine_integration_mode": 1, - "key_prefix": "key_prefix_value", - "delete_protection_state": 1, - "etag": "etag_value", + "retention": {"seconds": 751, "nanos": 543}, + "daily_recurrence": {}, + "weekly_recurrence": {"day": 1}, } # The version of a generated dependency at test runtime may differ from the version used during generation. # Delete any fields which are not present in the current runtime dependency # See https://github.com/googleapis/gapic-generator-python/issues/1748 # Determine if the message type is proto-plus or protobuf - test_field = firestore_admin.CreateDatabaseRequest.meta.fields["database"] + test_field = firestore_admin.CreateBackupScheduleRequest.meta.fields[ + "backup_schedule" + ] def get_message_fields(field): # Given a field which is a message (composite type), return a list with @@ -7602,7 +12200,7 @@ def get_message_fields(field): # For each item in the sample request, create a list of sub fields which are not present at runtime # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for field, value in request_init["database"].items(): # pragma: NO COVER + for field, value in request_init["backup_schedule"].items(): # pragma: NO COVER result = None is_repeated = False # For repeated fields @@ -7632,38 +12230,42 @@ def get_message_fields(field): subfield = subfield_to_delete.get("subfield") if subfield: if field_repeated: - for i in range(0, len(request_init["database"][field])): - del request_init["database"][field][i][subfield] + for i in range(0, len(request_init["backup_schedule"][field])): + del request_init["backup_schedule"][field][i][subfield] else: - del request_init["database"][field][subfield] + del request_init["backup_schedule"][field][subfield] request = request_type(**request_init) # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") + return_value = schedule.BackupSchedule( + name="name_value", + ) # Wrap the value into a proper Response obj response_value = Response() response_value.status_code = 200 + # Convert return value to protobuf type + return_value = schedule.BackupSchedule.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value - response = client.create_database(request) + response = client.create_backup_schedule(request) # Establish that the response is the type that we expect. - assert response.operation.name == "operations/spam" + assert isinstance(response, schedule.BackupSchedule) + assert response.name == "name_value" -def test_create_database_rest_required_fields( - request_type=firestore_admin.CreateDatabaseRequest, +def test_create_backup_schedule_rest_required_fields( + request_type=firestore_admin.CreateBackupScheduleRequest, ): transport_class = transports.FirestoreAdminRestTransport request_init = {} request_init["parent"] = "" - request_init["database_id"] = "" request = request_type(**request_init) pb_request = request_type.pb(request) jsonified_request = json.loads( @@ -7671,32 +12273,24 @@ def test_create_database_rest_required_fields( ) # verify fields with default values are dropped - assert "databaseId" not in jsonified_request unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).create_database._get_unset_required_fields(jsonified_request) + ).create_backup_schedule._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present - assert "databaseId" in jsonified_request - assert jsonified_request["databaseId"] == request_init["database_id"] jsonified_request["parent"] = "parent_value" - jsonified_request["databaseId"] = "database_id_value" unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).create_database._get_unset_required_fields(jsonified_request) - # Check that path parameters and body parameters are not mixing in. - assert not set(unset_fields) - set(("database_id",)) + ).create_backup_schedule._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone assert "parent" in jsonified_request assert jsonified_request["parent"] == "parent_value" - assert "databaseId" in jsonified_request - assert jsonified_request["databaseId"] == "database_id_value" client = FirestoreAdminClient( credentials=ga_credentials.AnonymousCredentials(), @@ -7705,7 +12299,7 @@ def test_create_database_rest_required_fields( request = request_type(**request_init) # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") + return_value = schedule.BackupSchedule() # Mock the http request call within the method and fake a response. with mock.patch.object(Session, "request") as req: # We need to mock transcode() because providing default values @@ -7725,44 +12319,40 @@ def test_create_database_rest_required_fields( response_value = Response() response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = schedule.BackupSchedule.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value - response = client.create_database(request) + response = client.create_backup_schedule(request) - expected_params = [ - ( - "databaseId", - "", - ), - ("$alt", "json;enum-encoding=int"), - ] + expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] assert expected_params == actual_params -def test_create_database_rest_unset_required_fields(): +def test_create_backup_schedule_rest_unset_required_fields(): transport = transports.FirestoreAdminRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.create_database._get_unset_required_fields({}) + unset_fields = transport.create_backup_schedule._get_unset_required_fields({}) assert set(unset_fields) == ( - set(("databaseId",)) + set(()) & set( ( "parent", - "database", - "databaseId", + "backupSchedule", ) ) ) @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_create_database_rest_interceptors(null_interceptor): +def test_create_backup_schedule_rest_interceptors(null_interceptor): transport = transports.FirestoreAdminRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -7775,16 +12365,14 @@ def test_create_database_rest_interceptors(null_interceptor): ) as req, mock.patch.object( path_template, "transcode" ) as transcode, mock.patch.object( - operation.Operation, "_set_result_from_operation" - ), mock.patch.object( - transports.FirestoreAdminRestInterceptor, "post_create_database" + transports.FirestoreAdminRestInterceptor, "post_create_backup_schedule" ) as post, mock.patch.object( - transports.FirestoreAdminRestInterceptor, "pre_create_database" + transports.FirestoreAdminRestInterceptor, "pre_create_backup_schedule" ) as pre: pre.assert_not_called() post.assert_not_called() - pb_message = firestore_admin.CreateDatabaseRequest.pb( - firestore_admin.CreateDatabaseRequest() + pb_message = firestore_admin.CreateBackupScheduleRequest.pb( + firestore_admin.CreateBackupScheduleRequest() ) transcode.return_value = { "method": "post", @@ -7796,19 +12384,19 @@ def test_create_database_rest_interceptors(null_interceptor): req.return_value = Response() req.return_value.status_code = 200 req.return_value.request = PreparedRequest() - req.return_value._content = json_format.MessageToJson( - operations_pb2.Operation() + req.return_value._content = schedule.BackupSchedule.to_json( + schedule.BackupSchedule() ) - request = firestore_admin.CreateDatabaseRequest() + request = firestore_admin.CreateBackupScheduleRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = operations_pb2.Operation() + post.return_value = schedule.BackupSchedule() - client.create_database( + client.create_backup_schedule( request, metadata=[ ("key", "val"), @@ -7820,8 +12408,8 @@ def test_create_database_rest_interceptors(null_interceptor): post.assert_called_once() -def test_create_database_rest_bad_request( - transport: str = "rest", request_type=firestore_admin.CreateDatabaseRequest +def test_create_backup_schedule_rest_bad_request( + transport: str = "rest", request_type=firestore_admin.CreateBackupScheduleRequest ): client = FirestoreAdminClient( credentials=ga_credentials.AnonymousCredentials(), @@ -7829,7 +12417,7 @@ def test_create_database_rest_bad_request( ) # send a request that will satisfy transcoding - request_init = {"parent": "projects/sample1"} + request_init = {"parent": "projects/sample1/databases/sample2"} request = request_type(**request_init) # Mock the http request call within the method and fake a BadRequest error. @@ -7841,10 +12429,10 @@ def test_create_database_rest_bad_request( response_value.status_code = 400 response_value.request = Request() req.return_value = response_value - client.create_database(request) + client.create_backup_schedule(request) -def test_create_database_rest_flattened(): +def test_create_backup_schedule_rest_flattened(): client = FirestoreAdminClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -7853,38 +12441,41 @@ def test_create_database_rest_flattened(): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") + return_value = schedule.BackupSchedule() # get arguments that satisfy an http rule for this method - sample_request = {"parent": "projects/sample1"} + sample_request = {"parent": "projects/sample1/databases/sample2"} # get truthy value for each flattened field mock_args = dict( parent="parent_value", - database=gfa_database.Database(name="name_value"), - database_id="database_id_value", + backup_schedule=schedule.BackupSchedule(name="name_value"), ) mock_args.update(sample_request) # Wrap the value into a proper Response obj response_value = Response() response_value.status_code = 200 + # Convert return value to protobuf type + return_value = schedule.BackupSchedule.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value - client.create_database(**mock_args) + client.create_backup_schedule(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1/{parent=projects/*}/databases" % client.transport._host, args[1] + "%s/v1/{parent=projects/*/databases/*}/backupSchedules" + % client.transport._host, + args[1], ) -def test_create_database_rest_flattened_error(transport: str = "rest"): +def test_create_backup_schedule_rest_flattened_error(transport: str = "rest"): client = FirestoreAdminClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -7893,15 +12484,14 @@ def test_create_database_rest_flattened_error(transport: str = "rest"): # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.create_database( - firestore_admin.CreateDatabaseRequest(), + client.create_backup_schedule( + firestore_admin.CreateBackupScheduleRequest(), parent="parent_value", - database=gfa_database.Database(name="name_value"), - database_id="database_id_value", + backup_schedule=schedule.BackupSchedule(name="name_value"), ) -def test_create_database_rest_error(): +def test_create_backup_schedule_rest_error(): client = FirestoreAdminClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) @@ -7910,72 +12500,47 @@ def test_create_database_rest_error(): @pytest.mark.parametrize( "request_type", [ - firestore_admin.GetDatabaseRequest, + firestore_admin.GetBackupScheduleRequest, dict, ], ) -def test_get_database_rest(request_type): +def test_get_backup_schedule_rest(request_type): client = FirestoreAdminClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", ) # send a request that will satisfy transcoding - request_init = {"name": "projects/sample1/databases/sample2"} + request_init = { + "name": "projects/sample1/databases/sample2/backupSchedules/sample3" + } request = request_type(**request_init) # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = database.Database( + return_value = schedule.BackupSchedule( name="name_value", - uid="uid_value", - location_id="location_id_value", - type_=database.Database.DatabaseType.FIRESTORE_NATIVE, - concurrency_mode=database.Database.ConcurrencyMode.OPTIMISTIC, - point_in_time_recovery_enablement=database.Database.PointInTimeRecoveryEnablement.POINT_IN_TIME_RECOVERY_ENABLED, - app_engine_integration_mode=database.Database.AppEngineIntegrationMode.ENABLED, - key_prefix="key_prefix_value", - delete_protection_state=database.Database.DeleteProtectionState.DELETE_PROTECTION_DISABLED, - etag="etag_value", ) # Wrap the value into a proper Response obj response_value = Response() response_value.status_code = 200 # Convert return value to protobuf type - return_value = database.Database.pb(return_value) + return_value = schedule.BackupSchedule.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value - response = client.get_database(request) + response = client.get_backup_schedule(request) # Establish that the response is the type that we expect. - assert isinstance(response, database.Database) + assert isinstance(response, schedule.BackupSchedule) assert response.name == "name_value" - assert response.uid == "uid_value" - assert response.location_id == "location_id_value" - assert response.type_ == database.Database.DatabaseType.FIRESTORE_NATIVE - assert response.concurrency_mode == database.Database.ConcurrencyMode.OPTIMISTIC - assert ( - response.point_in_time_recovery_enablement - == database.Database.PointInTimeRecoveryEnablement.POINT_IN_TIME_RECOVERY_ENABLED - ) - assert ( - response.app_engine_integration_mode - == database.Database.AppEngineIntegrationMode.ENABLED - ) - assert response.key_prefix == "key_prefix_value" - assert ( - response.delete_protection_state - == database.Database.DeleteProtectionState.DELETE_PROTECTION_DISABLED - ) - assert response.etag == "etag_value" -def test_get_database_rest_required_fields( - request_type=firestore_admin.GetDatabaseRequest, +def test_get_backup_schedule_rest_required_fields( + request_type=firestore_admin.GetBackupScheduleRequest, ): transport_class = transports.FirestoreAdminRestTransport @@ -7991,7 +12556,7 @@ def test_get_database_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).get_database._get_unset_required_fields(jsonified_request) + ).get_backup_schedule._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present @@ -8000,7 +12565,7 @@ def test_get_database_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).get_database._get_unset_required_fields(jsonified_request) + ).get_backup_schedule._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone @@ -8014,7 +12579,7 @@ def test_get_database_rest_required_fields( request = request_type(**request_init) # Designate an appropriate value for the returned response. - return_value = database.Database() + return_value = schedule.BackupSchedule() # Mock the http request call within the method and fake a response. with mock.patch.object(Session, "request") as req: # We need to mock transcode() because providing default values @@ -8035,30 +12600,30 @@ def test_get_database_rest_required_fields( response_value.status_code = 200 # Convert return value to protobuf type - return_value = database.Database.pb(return_value) + return_value = schedule.BackupSchedule.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value - response = client.get_database(request) + response = client.get_backup_schedule(request) expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] assert expected_params == actual_params -def test_get_database_rest_unset_required_fields(): +def test_get_backup_schedule_rest_unset_required_fields(): transport = transports.FirestoreAdminRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.get_database._get_unset_required_fields({}) + unset_fields = transport.get_backup_schedule._get_unset_required_fields({}) assert set(unset_fields) == (set(()) & set(("name",))) @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_get_database_rest_interceptors(null_interceptor): +def test_get_backup_schedule_rest_interceptors(null_interceptor): transport = transports.FirestoreAdminRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -8071,14 +12636,14 @@ def test_get_database_rest_interceptors(null_interceptor): ) as req, mock.patch.object( path_template, "transcode" ) as transcode, mock.patch.object( - transports.FirestoreAdminRestInterceptor, "post_get_database" + transports.FirestoreAdminRestInterceptor, "post_get_backup_schedule" ) as post, mock.patch.object( - transports.FirestoreAdminRestInterceptor, "pre_get_database" + transports.FirestoreAdminRestInterceptor, "pre_get_backup_schedule" ) as pre: pre.assert_not_called() post.assert_not_called() - pb_message = firestore_admin.GetDatabaseRequest.pb( - firestore_admin.GetDatabaseRequest() + pb_message = firestore_admin.GetBackupScheduleRequest.pb( + firestore_admin.GetBackupScheduleRequest() ) transcode.return_value = { "method": "post", @@ -8090,17 +12655,19 @@ def test_get_database_rest_interceptors(null_interceptor): req.return_value = Response() req.return_value.status_code = 200 req.return_value.request = PreparedRequest() - req.return_value._content = database.Database.to_json(database.Database()) + req.return_value._content = schedule.BackupSchedule.to_json( + schedule.BackupSchedule() + ) - request = firestore_admin.GetDatabaseRequest() + request = firestore_admin.GetBackupScheduleRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = database.Database() + post.return_value = schedule.BackupSchedule() - client.get_database( + client.get_backup_schedule( request, metadata=[ ("key", "val"), @@ -8112,8 +12679,8 @@ def test_get_database_rest_interceptors(null_interceptor): post.assert_called_once() -def test_get_database_rest_bad_request( - transport: str = "rest", request_type=firestore_admin.GetDatabaseRequest +def test_get_backup_schedule_rest_bad_request( + transport: str = "rest", request_type=firestore_admin.GetBackupScheduleRequest ): client = FirestoreAdminClient( credentials=ga_credentials.AnonymousCredentials(), @@ -8121,7 +12688,9 @@ def test_get_database_rest_bad_request( ) # send a request that will satisfy transcoding - request_init = {"name": "projects/sample1/databases/sample2"} + request_init = { + "name": "projects/sample1/databases/sample2/backupSchedules/sample3" + } request = request_type(**request_init) # Mock the http request call within the method and fake a BadRequest error. @@ -8133,10 +12702,10 @@ def test_get_database_rest_bad_request( response_value.status_code = 400 response_value.request = Request() req.return_value = response_value - client.get_database(request) + client.get_backup_schedule(request) -def test_get_database_rest_flattened(): +def test_get_backup_schedule_rest_flattened(): client = FirestoreAdminClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -8145,10 +12714,12 @@ def test_get_database_rest_flattened(): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = database.Database() + return_value = schedule.BackupSchedule() # get arguments that satisfy an http rule for this method - sample_request = {"name": "projects/sample1/databases/sample2"} + sample_request = { + "name": "projects/sample1/databases/sample2/backupSchedules/sample3" + } # get truthy value for each flattened field mock_args = dict( @@ -8160,23 +12731,25 @@ def test_get_database_rest_flattened(): response_value = Response() response_value.status_code = 200 # Convert return value to protobuf type - return_value = database.Database.pb(return_value) + return_value = schedule.BackupSchedule.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value - client.get_database(**mock_args) + client.get_backup_schedule(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1/{name=projects/*/databases/*}" % client.transport._host, args[1] + "%s/v1/{name=projects/*/databases/*/backupSchedules/*}" + % client.transport._host, + args[1], ) -def test_get_database_rest_flattened_error(transport: str = "rest"): +def test_get_backup_schedule_rest_flattened_error(transport: str = "rest"): client = FirestoreAdminClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -8185,13 +12758,13 @@ def test_get_database_rest_flattened_error(transport: str = "rest"): # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.get_database( - firestore_admin.GetDatabaseRequest(), + client.get_backup_schedule( + firestore_admin.GetBackupScheduleRequest(), name="name_value", ) -def test_get_database_rest_error(): +def test_get_backup_schedule_rest_error(): client = FirestoreAdminClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) @@ -8200,45 +12773,42 @@ def test_get_database_rest_error(): @pytest.mark.parametrize( "request_type", [ - firestore_admin.ListDatabasesRequest, + firestore_admin.ListBackupSchedulesRequest, dict, ], ) -def test_list_databases_rest(request_type): +def test_list_backup_schedules_rest(request_type): client = FirestoreAdminClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", ) # send a request that will satisfy transcoding - request_init = {"parent": "projects/sample1"} + request_init = {"parent": "projects/sample1/databases/sample2"} request = request_type(**request_init) # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = firestore_admin.ListDatabasesResponse( - unreachable=["unreachable_value"], - ) + return_value = firestore_admin.ListBackupSchedulesResponse() # Wrap the value into a proper Response obj response_value = Response() response_value.status_code = 200 # Convert return value to protobuf type - return_value = firestore_admin.ListDatabasesResponse.pb(return_value) + return_value = firestore_admin.ListBackupSchedulesResponse.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value - response = client.list_databases(request) + response = client.list_backup_schedules(request) # Establish that the response is the type that we expect. - assert isinstance(response, firestore_admin.ListDatabasesResponse) - assert response.unreachable == ["unreachable_value"] + assert isinstance(response, firestore_admin.ListBackupSchedulesResponse) -def test_list_databases_rest_required_fields( - request_type=firestore_admin.ListDatabasesRequest, +def test_list_backup_schedules_rest_required_fields( + request_type=firestore_admin.ListBackupSchedulesRequest, ): transport_class = transports.FirestoreAdminRestTransport @@ -8254,7 +12824,7 @@ def test_list_databases_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).list_databases._get_unset_required_fields(jsonified_request) + ).list_backup_schedules._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present @@ -8263,7 +12833,7 @@ def test_list_databases_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).list_databases._get_unset_required_fields(jsonified_request) + ).list_backup_schedules._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone @@ -8277,7 +12847,7 @@ def test_list_databases_rest_required_fields( request = request_type(**request_init) # Designate an appropriate value for the returned response. - return_value = firestore_admin.ListDatabasesResponse() + return_value = firestore_admin.ListBackupSchedulesResponse() # Mock the http request call within the method and fake a response. with mock.patch.object(Session, "request") as req: # We need to mock transcode() because providing default values @@ -8298,30 +12868,30 @@ def test_list_databases_rest_required_fields( response_value.status_code = 200 # Convert return value to protobuf type - return_value = firestore_admin.ListDatabasesResponse.pb(return_value) + return_value = firestore_admin.ListBackupSchedulesResponse.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value - response = client.list_databases(request) + response = client.list_backup_schedules(request) expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] assert expected_params == actual_params -def test_list_databases_rest_unset_required_fields(): +def test_list_backup_schedules_rest_unset_required_fields(): transport = transports.FirestoreAdminRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.list_databases._get_unset_required_fields({}) + unset_fields = transport.list_backup_schedules._get_unset_required_fields({}) assert set(unset_fields) == (set(()) & set(("parent",))) @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_list_databases_rest_interceptors(null_interceptor): +def test_list_backup_schedules_rest_interceptors(null_interceptor): transport = transports.FirestoreAdminRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -8334,14 +12904,14 @@ def test_list_databases_rest_interceptors(null_interceptor): ) as req, mock.patch.object( path_template, "transcode" ) as transcode, mock.patch.object( - transports.FirestoreAdminRestInterceptor, "post_list_databases" + transports.FirestoreAdminRestInterceptor, "post_list_backup_schedules" ) as post, mock.patch.object( - transports.FirestoreAdminRestInterceptor, "pre_list_databases" + transports.FirestoreAdminRestInterceptor, "pre_list_backup_schedules" ) as pre: pre.assert_not_called() post.assert_not_called() - pb_message = firestore_admin.ListDatabasesRequest.pb( - firestore_admin.ListDatabasesRequest() + pb_message = firestore_admin.ListBackupSchedulesRequest.pb( + firestore_admin.ListBackupSchedulesRequest() ) transcode.return_value = { "method": "post", @@ -8353,19 +12923,19 @@ def test_list_databases_rest_interceptors(null_interceptor): req.return_value = Response() req.return_value.status_code = 200 req.return_value.request = PreparedRequest() - req.return_value._content = firestore_admin.ListDatabasesResponse.to_json( - firestore_admin.ListDatabasesResponse() + req.return_value._content = firestore_admin.ListBackupSchedulesResponse.to_json( + firestore_admin.ListBackupSchedulesResponse() ) - request = firestore_admin.ListDatabasesRequest() + request = firestore_admin.ListBackupSchedulesRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = firestore_admin.ListDatabasesResponse() + post.return_value = firestore_admin.ListBackupSchedulesResponse() - client.list_databases( + client.list_backup_schedules( request, metadata=[ ("key", "val"), @@ -8377,8 +12947,8 @@ def test_list_databases_rest_interceptors(null_interceptor): post.assert_called_once() -def test_list_databases_rest_bad_request( - transport: str = "rest", request_type=firestore_admin.ListDatabasesRequest +def test_list_backup_schedules_rest_bad_request( + transport: str = "rest", request_type=firestore_admin.ListBackupSchedulesRequest ): client = FirestoreAdminClient( credentials=ga_credentials.AnonymousCredentials(), @@ -8386,7 +12956,7 @@ def test_list_databases_rest_bad_request( ) # send a request that will satisfy transcoding - request_init = {"parent": "projects/sample1"} + request_init = {"parent": "projects/sample1/databases/sample2"} request = request_type(**request_init) # Mock the http request call within the method and fake a BadRequest error. @@ -8398,10 +12968,10 @@ def test_list_databases_rest_bad_request( response_value.status_code = 400 response_value.request = Request() req.return_value = response_value - client.list_databases(request) + client.list_backup_schedules(request) -def test_list_databases_rest_flattened(): +def test_list_backup_schedules_rest_flattened(): client = FirestoreAdminClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -8410,10 +12980,10 @@ def test_list_databases_rest_flattened(): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = firestore_admin.ListDatabasesResponse() + return_value = firestore_admin.ListBackupSchedulesResponse() # get arguments that satisfy an http rule for this method - sample_request = {"parent": "projects/sample1"} + sample_request = {"parent": "projects/sample1/databases/sample2"} # get truthy value for each flattened field mock_args = dict( @@ -8425,23 +12995,25 @@ def test_list_databases_rest_flattened(): response_value = Response() response_value.status_code = 200 # Convert return value to protobuf type - return_value = firestore_admin.ListDatabasesResponse.pb(return_value) + return_value = firestore_admin.ListBackupSchedulesResponse.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value - client.list_databases(**mock_args) + client.list_backup_schedules(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1/{parent=projects/*}/databases" % client.transport._host, args[1] + "%s/v1/{parent=projects/*/databases/*}/backupSchedules" + % client.transport._host, + args[1], ) -def test_list_databases_rest_flattened_error(transport: str = "rest"): +def test_list_backup_schedules_rest_flattened_error(transport: str = "rest"): client = FirestoreAdminClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -8450,13 +13022,13 @@ def test_list_databases_rest_flattened_error(transport: str = "rest"): # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.list_databases( - firestore_admin.ListDatabasesRequest(), + client.list_backup_schedules( + firestore_admin.ListBackupSchedulesRequest(), parent="parent_value", ) -def test_list_databases_rest_error(): +def test_list_backup_schedules_rest_error(): client = FirestoreAdminClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) @@ -8465,40 +13037,38 @@ def test_list_databases_rest_error(): @pytest.mark.parametrize( "request_type", [ - firestore_admin.UpdateDatabaseRequest, + firestore_admin.UpdateBackupScheduleRequest, dict, ], ) -def test_update_database_rest(request_type): +def test_update_backup_schedule_rest(request_type): client = FirestoreAdminClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", ) # send a request that will satisfy transcoding - request_init = {"database": {"name": "projects/sample1/databases/sample2"}} - request_init["database"] = { - "name": "projects/sample1/databases/sample2", - "uid": "uid_value", + request_init = { + "backup_schedule": { + "name": "projects/sample1/databases/sample2/backupSchedules/sample3" + } + } + request_init["backup_schedule"] = { + "name": "projects/sample1/databases/sample2/backupSchedules/sample3", "create_time": {"seconds": 751, "nanos": 543}, "update_time": {}, - "location_id": "location_id_value", - "type_": 1, - "concurrency_mode": 1, - "version_retention_period": {"seconds": 751, "nanos": 543}, - "earliest_version_time": {}, - "point_in_time_recovery_enablement": 1, - "app_engine_integration_mode": 1, - "key_prefix": "key_prefix_value", - "delete_protection_state": 1, - "etag": "etag_value", + "retention": {"seconds": 751, "nanos": 543}, + "daily_recurrence": {}, + "weekly_recurrence": {"day": 1}, } # The version of a generated dependency at test runtime may differ from the version used during generation. # Delete any fields which are not present in the current runtime dependency # See https://github.com/googleapis/gapic-generator-python/issues/1748 # Determine if the message type is proto-plus or protobuf - test_field = firestore_admin.UpdateDatabaseRequest.meta.fields["database"] + test_field = firestore_admin.UpdateBackupScheduleRequest.meta.fields[ + "backup_schedule" + ] def get_message_fields(field): # Given a field which is a message (composite type), return a list with @@ -8526,7 +13096,7 @@ def get_message_fields(field): # For each item in the sample request, create a list of sub fields which are not present at runtime # Add `# pragma: NO COVER` because this test code will not run if all subfields are present at runtime - for field, value in request_init["database"].items(): # pragma: NO COVER + for field, value in request_init["backup_schedule"].items(): # pragma: NO COVER result = None is_repeated = False # For repeated fields @@ -8556,32 +13126,37 @@ def get_message_fields(field): subfield = subfield_to_delete.get("subfield") if subfield: if field_repeated: - for i in range(0, len(request_init["database"][field])): - del request_init["database"][field][i][subfield] + for i in range(0, len(request_init["backup_schedule"][field])): + del request_init["backup_schedule"][field][i][subfield] else: - del request_init["database"][field][subfield] + del request_init["backup_schedule"][field][subfield] request = request_type(**request_init) # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") + return_value = schedule.BackupSchedule( + name="name_value", + ) # Wrap the value into a proper Response obj response_value = Response() response_value.status_code = 200 + # Convert return value to protobuf type + return_value = schedule.BackupSchedule.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value - response = client.update_database(request) + response = client.update_backup_schedule(request) # Establish that the response is the type that we expect. - assert response.operation.name == "operations/spam" + assert isinstance(response, schedule.BackupSchedule) + assert response.name == "name_value" -def test_update_database_rest_required_fields( - request_type=firestore_admin.UpdateDatabaseRequest, +def test_update_backup_schedule_rest_required_fields( + request_type=firestore_admin.UpdateBackupScheduleRequest, ): transport_class = transports.FirestoreAdminRestTransport @@ -8596,14 +13171,14 @@ def test_update_database_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).update_database._get_unset_required_fields(jsonified_request) + ).update_backup_schedule._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).update_database._get_unset_required_fields(jsonified_request) + ).update_backup_schedule._get_unset_required_fields(jsonified_request) # Check that path parameters and body parameters are not mixing in. assert not set(unset_fields) - set(("update_mask",)) jsonified_request.update(unset_fields) @@ -8617,7 +13192,7 @@ def test_update_database_rest_required_fields( request = request_type(**request_init) # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") + return_value = schedule.BackupSchedule() # Mock the http request call within the method and fake a response. with mock.patch.object(Session, "request") as req: # We need to mock transcode() because providing default values @@ -8637,29 +13212,32 @@ def test_update_database_rest_required_fields( response_value = Response() response_value.status_code = 200 + + # Convert return value to protobuf type + return_value = schedule.BackupSchedule.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value - response = client.update_database(request) + response = client.update_backup_schedule(request) expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] assert expected_params == actual_params -def test_update_database_rest_unset_required_fields(): +def test_update_backup_schedule_rest_unset_required_fields(): transport = transports.FirestoreAdminRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.update_database._get_unset_required_fields({}) - assert set(unset_fields) == (set(("updateMask",)) & set(("database",))) + unset_fields = transport.update_backup_schedule._get_unset_required_fields({}) + assert set(unset_fields) == (set(("updateMask",)) & set(("backupSchedule",))) @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_update_database_rest_interceptors(null_interceptor): +def test_update_backup_schedule_rest_interceptors(null_interceptor): transport = transports.FirestoreAdminRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -8672,16 +13250,14 @@ def test_update_database_rest_interceptors(null_interceptor): ) as req, mock.patch.object( path_template, "transcode" ) as transcode, mock.patch.object( - operation.Operation, "_set_result_from_operation" - ), mock.patch.object( - transports.FirestoreAdminRestInterceptor, "post_update_database" + transports.FirestoreAdminRestInterceptor, "post_update_backup_schedule" ) as post, mock.patch.object( - transports.FirestoreAdminRestInterceptor, "pre_update_database" + transports.FirestoreAdminRestInterceptor, "pre_update_backup_schedule" ) as pre: pre.assert_not_called() post.assert_not_called() - pb_message = firestore_admin.UpdateDatabaseRequest.pb( - firestore_admin.UpdateDatabaseRequest() + pb_message = firestore_admin.UpdateBackupScheduleRequest.pb( + firestore_admin.UpdateBackupScheduleRequest() ) transcode.return_value = { "method": "post", @@ -8693,19 +13269,19 @@ def test_update_database_rest_interceptors(null_interceptor): req.return_value = Response() req.return_value.status_code = 200 req.return_value.request = PreparedRequest() - req.return_value._content = json_format.MessageToJson( - operations_pb2.Operation() + req.return_value._content = schedule.BackupSchedule.to_json( + schedule.BackupSchedule() ) - request = firestore_admin.UpdateDatabaseRequest() + request = firestore_admin.UpdateBackupScheduleRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = operations_pb2.Operation() + post.return_value = schedule.BackupSchedule() - client.update_database( + client.update_backup_schedule( request, metadata=[ ("key", "val"), @@ -8717,8 +13293,8 @@ def test_update_database_rest_interceptors(null_interceptor): post.assert_called_once() -def test_update_database_rest_bad_request( - transport: str = "rest", request_type=firestore_admin.UpdateDatabaseRequest +def test_update_backup_schedule_rest_bad_request( + transport: str = "rest", request_type=firestore_admin.UpdateBackupScheduleRequest ): client = FirestoreAdminClient( credentials=ga_credentials.AnonymousCredentials(), @@ -8726,7 +13302,11 @@ def test_update_database_rest_bad_request( ) # send a request that will satisfy transcoding - request_init = {"database": {"name": "projects/sample1/databases/sample2"}} + request_init = { + "backup_schedule": { + "name": "projects/sample1/databases/sample2/backupSchedules/sample3" + } + } request = request_type(**request_init) # Mock the http request call within the method and fake a BadRequest error. @@ -8738,10 +13318,10 @@ def test_update_database_rest_bad_request( response_value.status_code = 400 response_value.request = Request() req.return_value = response_value - client.update_database(request) + client.update_backup_schedule(request) -def test_update_database_rest_flattened(): +def test_update_backup_schedule_rest_flattened(): client = FirestoreAdminClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -8750,14 +13330,18 @@ def test_update_database_rest_flattened(): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") + return_value = schedule.BackupSchedule() # get arguments that satisfy an http rule for this method - sample_request = {"database": {"name": "projects/sample1/databases/sample2"}} + sample_request = { + "backup_schedule": { + "name": "projects/sample1/databases/sample2/backupSchedules/sample3" + } + } # get truthy value for each flattened field mock_args = dict( - database=gfa_database.Database(name="name_value"), + backup_schedule=schedule.BackupSchedule(name="name_value"), update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), ) mock_args.update(sample_request) @@ -8765,23 +13349,26 @@ def test_update_database_rest_flattened(): # Wrap the value into a proper Response obj response_value = Response() response_value.status_code = 200 + # Convert return value to protobuf type + return_value = schedule.BackupSchedule.pb(return_value) json_return_value = json_format.MessageToJson(return_value) response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value - client.update_database(**mock_args) + client.update_backup_schedule(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1/{database.name=projects/*/databases/*}" % client.transport._host, + "%s/v1/{backup_schedule.name=projects/*/databases/*/backupSchedules/*}" + % client.transport._host, args[1], ) -def test_update_database_rest_flattened_error(transport: str = "rest"): +def test_update_backup_schedule_rest_flattened_error(transport: str = "rest"): client = FirestoreAdminClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -8790,14 +13377,14 @@ def test_update_database_rest_flattened_error(transport: str = "rest"): # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.update_database( - firestore_admin.UpdateDatabaseRequest(), - database=gfa_database.Database(name="name_value"), + client.update_backup_schedule( + firestore_admin.UpdateBackupScheduleRequest(), + backup_schedule=schedule.BackupSchedule(name="name_value"), update_mask=field_mask_pb2.FieldMask(paths=["paths_value"]), ) -def test_update_database_rest_error(): +def test_update_backup_schedule_rest_error(): client = FirestoreAdminClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) @@ -8806,40 +13393,42 @@ def test_update_database_rest_error(): @pytest.mark.parametrize( "request_type", [ - firestore_admin.DeleteDatabaseRequest, + firestore_admin.DeleteBackupScheduleRequest, dict, ], ) -def test_delete_database_rest(request_type): +def test_delete_backup_schedule_rest(request_type): client = FirestoreAdminClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", ) # send a request that will satisfy transcoding - request_init = {"name": "projects/sample1/databases/sample2"} + request_init = { + "name": "projects/sample1/databases/sample2/backupSchedules/sample3" + } request = request_type(**request_init) # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") + return_value = None # Wrap the value into a proper Response obj response_value = Response() response_value.status_code = 200 - json_return_value = json_format.MessageToJson(return_value) + json_return_value = "" response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value - response = client.delete_database(request) + response = client.delete_backup_schedule(request) # Establish that the response is the type that we expect. - assert response.operation.name == "operations/spam" + assert response is None -def test_delete_database_rest_required_fields( - request_type=firestore_admin.DeleteDatabaseRequest, +def test_delete_backup_schedule_rest_required_fields( + request_type=firestore_admin.DeleteBackupScheduleRequest, ): transport_class = transports.FirestoreAdminRestTransport @@ -8855,7 +13444,7 @@ def test_delete_database_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).delete_database._get_unset_required_fields(jsonified_request) + ).delete_backup_schedule._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with default values are now present @@ -8864,9 +13453,7 @@ def test_delete_database_rest_required_fields( unset_fields = transport_class( credentials=ga_credentials.AnonymousCredentials() - ).delete_database._get_unset_required_fields(jsonified_request) - # Check that path parameters and body parameters are not mixing in. - assert not set(unset_fields) - set(("etag",)) + ).delete_backup_schedule._get_unset_required_fields(jsonified_request) jsonified_request.update(unset_fields) # verify required fields with non-default values are left alone @@ -8880,7 +13467,7 @@ def test_delete_database_rest_required_fields( request = request_type(**request_init) # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") + return_value = None # Mock the http request call within the method and fake a response. with mock.patch.object(Session, "request") as req: # We need to mock transcode() because providing default values @@ -8899,29 +13486,29 @@ def test_delete_database_rest_required_fields( response_value = Response() response_value.status_code = 200 - json_return_value = json_format.MessageToJson(return_value) + json_return_value = "" response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value - response = client.delete_database(request) + response = client.delete_backup_schedule(request) expected_params = [("$alt", "json;enum-encoding=int")] actual_params = req.call_args.kwargs["params"] assert expected_params == actual_params -def test_delete_database_rest_unset_required_fields(): +def test_delete_backup_schedule_rest_unset_required_fields(): transport = transports.FirestoreAdminRestTransport( credentials=ga_credentials.AnonymousCredentials ) - unset_fields = transport.delete_database._get_unset_required_fields({}) - assert set(unset_fields) == (set(("etag",)) & set(("name",))) + unset_fields = transport.delete_backup_schedule._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name",))) @pytest.mark.parametrize("null_interceptor", [True, False]) -def test_delete_database_rest_interceptors(null_interceptor): +def test_delete_backup_schedule_rest_interceptors(null_interceptor): transport = transports.FirestoreAdminRestTransport( credentials=ga_credentials.AnonymousCredentials(), interceptor=None @@ -8934,16 +13521,11 @@ def test_delete_database_rest_interceptors(null_interceptor): ) as req, mock.patch.object( path_template, "transcode" ) as transcode, mock.patch.object( - operation.Operation, "_set_result_from_operation" - ), mock.patch.object( - transports.FirestoreAdminRestInterceptor, "post_delete_database" - ) as post, mock.patch.object( - transports.FirestoreAdminRestInterceptor, "pre_delete_database" + transports.FirestoreAdminRestInterceptor, "pre_delete_backup_schedule" ) as pre: pre.assert_not_called() - post.assert_not_called() - pb_message = firestore_admin.DeleteDatabaseRequest.pb( - firestore_admin.DeleteDatabaseRequest() + pb_message = firestore_admin.DeleteBackupScheduleRequest.pb( + firestore_admin.DeleteBackupScheduleRequest() ) transcode.return_value = { "method": "post", @@ -8955,19 +13537,15 @@ def test_delete_database_rest_interceptors(null_interceptor): req.return_value = Response() req.return_value.status_code = 200 req.return_value.request = PreparedRequest() - req.return_value._content = json_format.MessageToJson( - operations_pb2.Operation() - ) - request = firestore_admin.DeleteDatabaseRequest() + request = firestore_admin.DeleteBackupScheduleRequest() metadata = [ ("key", "val"), ("cephalopod", "squid"), ] pre.return_value = request, metadata - post.return_value = operations_pb2.Operation() - client.delete_database( + client.delete_backup_schedule( request, metadata=[ ("key", "val"), @@ -8976,11 +13554,10 @@ def test_delete_database_rest_interceptors(null_interceptor): ) pre.assert_called_once() - post.assert_called_once() -def test_delete_database_rest_bad_request( - transport: str = "rest", request_type=firestore_admin.DeleteDatabaseRequest +def test_delete_backup_schedule_rest_bad_request( + transport: str = "rest", request_type=firestore_admin.DeleteBackupScheduleRequest ): client = FirestoreAdminClient( credentials=ga_credentials.AnonymousCredentials(), @@ -8988,7 +13565,9 @@ def test_delete_database_rest_bad_request( ) # send a request that will satisfy transcoding - request_init = {"name": "projects/sample1/databases/sample2"} + request_init = { + "name": "projects/sample1/databases/sample2/backupSchedules/sample3" + } request = request_type(**request_init) # Mock the http request call within the method and fake a BadRequest error. @@ -9000,10 +13579,10 @@ def test_delete_database_rest_bad_request( response_value.status_code = 400 response_value.request = Request() req.return_value = response_value - client.delete_database(request) + client.delete_backup_schedule(request) -def test_delete_database_rest_flattened(): +def test_delete_backup_schedule_rest_flattened(): client = FirestoreAdminClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest", @@ -9012,10 +13591,12 @@ def test_delete_database_rest_flattened(): # Mock the http request call within the method and fake a response. with mock.patch.object(type(client.transport._session), "request") as req: # Designate an appropriate value for the returned response. - return_value = operations_pb2.Operation(name="operations/spam") + return_value = None # get arguments that satisfy an http rule for this method - sample_request = {"name": "projects/sample1/databases/sample2"} + sample_request = { + "name": "projects/sample1/databases/sample2/backupSchedules/sample3" + } # get truthy value for each flattened field mock_args = dict( @@ -9026,22 +13607,24 @@ def test_delete_database_rest_flattened(): # Wrap the value into a proper Response obj response_value = Response() response_value.status_code = 200 - json_return_value = json_format.MessageToJson(return_value) + json_return_value = "" response_value._content = json_return_value.encode("UTF-8") req.return_value = response_value - client.delete_database(**mock_args) + client.delete_backup_schedule(**mock_args) # Establish that the underlying call was made with the expected # request object values. assert len(req.mock_calls) == 1 _, args, _ = req.mock_calls[0] assert path_template.validate( - "%s/v1/{name=projects/*/databases/*}" % client.transport._host, args[1] + "%s/v1/{name=projects/*/databases/*/backupSchedules/*}" + % client.transport._host, + args[1], ) -def test_delete_database_rest_flattened_error(transport: str = "rest"): +def test_delete_backup_schedule_rest_flattened_error(transport: str = "rest"): client = FirestoreAdminClient( credentials=ga_credentials.AnonymousCredentials(), transport=transport, @@ -9050,13 +13633,13 @@ def test_delete_database_rest_flattened_error(transport: str = "rest"): # Attempting to call a method with both a request object and flattened # fields is an error. with pytest.raises(ValueError): - client.delete_database( - firestore_admin.DeleteDatabaseRequest(), + client.delete_backup_schedule( + firestore_admin.DeleteBackupScheduleRequest(), name="name_value", ) -def test_delete_database_rest_error(): +def test_delete_backup_schedule_rest_error(): client = FirestoreAdminClient( credentials=ga_credentials.AnonymousCredentials(), transport="rest" ) @@ -9215,6 +13798,15 @@ def test_firestore_admin_base_transport(): "list_databases", "update_database", "delete_database", + "get_backup", + "list_backups", + "delete_backup", + "restore_database", + "create_backup_schedule", + "get_backup_schedule", + "list_backup_schedules", + "update_backup_schedule", + "delete_backup_schedule", "get_operation", "cancel_operation", "delete_operation", @@ -9553,6 +14145,33 @@ def test_firestore_admin_client_transport_session_collision(transport_name): session1 = client1.transport.delete_database._session session2 = client2.transport.delete_database._session assert session1 != session2 + session1 = client1.transport.get_backup._session + session2 = client2.transport.get_backup._session + assert session1 != session2 + session1 = client1.transport.list_backups._session + session2 = client2.transport.list_backups._session + assert session1 != session2 + session1 = client1.transport.delete_backup._session + session2 = client2.transport.delete_backup._session + assert session1 != session2 + session1 = client1.transport.restore_database._session + session2 = client2.transport.restore_database._session + assert session1 != session2 + session1 = client1.transport.create_backup_schedule._session + session2 = client2.transport.create_backup_schedule._session + assert session1 != session2 + session1 = client1.transport.get_backup_schedule._session + session2 = client2.transport.get_backup_schedule._session + assert session1 != session2 + session1 = client1.transport.list_backup_schedules._session + session2 = client2.transport.list_backup_schedules._session + assert session1 != session2 + session1 = client1.transport.update_backup_schedule._session + session2 = client2.transport.update_backup_schedule._session + assert session1 != session2 + session1 = client1.transport.delete_backup_schedule._session + session2 = client2.transport.delete_backup_schedule._session + assert session1 != session2 def test_firestore_admin_grpc_transport_channel(): @@ -9715,6 +14334,60 @@ def test_firestore_admin_grpc_lro_async_client(): assert transport.operations_client is transport.operations_client +def test_backup_path(): + project = "squid" + location = "clam" + backup = "whelk" + expected = "projects/{project}/locations/{location}/backups/{backup}".format( + project=project, + location=location, + backup=backup, + ) + actual = FirestoreAdminClient.backup_path(project, location, backup) + assert expected == actual + + +def test_parse_backup_path(): + expected = { + "project": "octopus", + "location": "oyster", + "backup": "nudibranch", + } + path = FirestoreAdminClient.backup_path(**expected) + + # Check that the path construction is reversible. + actual = FirestoreAdminClient.parse_backup_path(path) + assert expected == actual + + +def test_backup_schedule_path(): + project = "cuttlefish" + database = "mussel" + backup_schedule = "winkle" + expected = "projects/{project}/databases/{database}/backupSchedules/{backup_schedule}".format( + project=project, + database=database, + backup_schedule=backup_schedule, + ) + actual = FirestoreAdminClient.backup_schedule_path( + project, database, backup_schedule + ) + assert expected == actual + + +def test_parse_backup_schedule_path(): + expected = { + "project": "nautilus", + "database": "scallop", + "backup_schedule": "abalone", + } + path = FirestoreAdminClient.backup_schedule_path(**expected) + + # Check that the path construction is reversible. + actual = FirestoreAdminClient.parse_backup_schedule_path(path) + assert expected == actual + + def test_collection_group_path(): project = "squid" database = "clam" @@ -9824,8 +14497,31 @@ def test_parse_index_path(): assert expected == actual +def test_location_path(): + project = "whelk" + location = "octopus" + expected = "projects/{project}/locations/{location}".format( + project=project, + location=location, + ) + actual = FirestoreAdminClient.location_path(project, location) + assert expected == actual + + +def test_parse_location_path(): + expected = { + "project": "oyster", + "location": "nudibranch", + } + path = FirestoreAdminClient.location_path(**expected) + + # Check that the path construction is reversible. + actual = FirestoreAdminClient.parse_location_path(path) + assert expected == actual + + def test_common_billing_account_path(): - billing_account = "whelk" + billing_account = "cuttlefish" expected = "billingAccounts/{billing_account}".format( billing_account=billing_account, ) @@ -9835,7 +14531,7 @@ def test_common_billing_account_path(): def test_parse_common_billing_account_path(): expected = { - "billing_account": "octopus", + "billing_account": "mussel", } path = FirestoreAdminClient.common_billing_account_path(**expected) @@ -9845,7 +14541,7 @@ def test_parse_common_billing_account_path(): def test_common_folder_path(): - folder = "oyster" + folder = "winkle" expected = "folders/{folder}".format( folder=folder, ) @@ -9855,7 +14551,7 @@ def test_common_folder_path(): def test_parse_common_folder_path(): expected = { - "folder": "nudibranch", + "folder": "nautilus", } path = FirestoreAdminClient.common_folder_path(**expected) @@ -9865,7 +14561,7 @@ def test_parse_common_folder_path(): def test_common_organization_path(): - organization = "cuttlefish" + organization = "scallop" expected = "organizations/{organization}".format( organization=organization, ) @@ -9875,7 +14571,7 @@ def test_common_organization_path(): def test_parse_common_organization_path(): expected = { - "organization": "mussel", + "organization": "abalone", } path = FirestoreAdminClient.common_organization_path(**expected) @@ -9885,7 +14581,7 @@ def test_parse_common_organization_path(): def test_common_project_path(): - project = "winkle" + project = "squid" expected = "projects/{project}".format( project=project, ) @@ -9895,7 +14591,7 @@ def test_common_project_path(): def test_parse_common_project_path(): expected = { - "project": "nautilus", + "project": "clam", } path = FirestoreAdminClient.common_project_path(**expected) @@ -9905,8 +14601,8 @@ def test_parse_common_project_path(): def test_common_location_path(): - project = "scallop" - location = "abalone" + project = "whelk" + location = "octopus" expected = "projects/{project}/locations/{location}".format( project=project, location=location, @@ -9917,8 +14613,8 @@ def test_common_location_path(): def test_parse_common_location_path(): expected = { - "project": "squid", - "location": "clam", + "project": "oyster", + "location": "nudibranch", } path = FirestoreAdminClient.common_location_path(**expected) diff --git a/tests/unit/gapic/firestore_v1/test_firestore.py b/tests/unit/gapic/firestore_v1/test_firestore.py index c09f2dc05..9a20159ec 100644 --- a/tests/unit/gapic/firestore_v1/test_firestore.py +++ b/tests/unit/gapic/firestore_v1/test_firestore.py @@ -55,6 +55,7 @@ from google.cloud.firestore_v1.types import document as gf_document from google.cloud.firestore_v1.types import firestore from google.cloud.firestore_v1.types import query +from google.cloud.firestore_v1.types import query_profile from google.cloud.firestore_v1.types import write as gf_write from google.cloud.location import locations_pb2 from google.longrunning import operations_pb2 # type: ignore